public void adminSetGroupOffSetByTime(HttpServletRequest req, StringBuilder sBuffer) {
        ProcessResult result = new ProcessResult();
        // get group name
        if (!WebParameterUtils.getStringParamValue(req,
                WebFieldDef.GROUPNAME, true, null, sBuffer, result)) {
            WebParameterUtils.buildFailResult(sBuffer, result.getErrMsg());
            return;
        }
        final String groupName = (String) result.getRetData();
        // get modify user
        if (!WebParameterUtils.getStringParamValue(req,
                WebFieldDef.MODIFYUSER, true, null, sBuffer, result)) {
            WebParameterUtils.buildFailResult(sBuffer, result.getErrMsg());
            return;
        }
        final String modifyUser = (String) result.getRetData();
        // get the left timestamp to be set
        if (!WebParameterUtils.getDateParameter(req,
                WebFieldDef.RECORDTIME, true, null, sBuffer, result)) {
            WebParameterUtils.buildFailResult(sBuffer, result.getErrMsg());
            return;
        }
        final Date tmpDataTime1 = (Date) result.getRetData();
        final long recStartTime = tmpDataTime1.getTime();
        // get the right timestamp to be set
        if (!WebParameterUtils.getDateParameter(req,
                WebFieldDef.ENDTIME, false, null, sBuffer, result)) {
            WebParameterUtils.buildFailResult(sBuffer, result.getErrMsg());
            return;
        }
        final Date tmpDataTime2 = (Date) result.getRetData();
        long recEndTime = recStartTime + 5 * 60 * 1000L;
        if (tmpDataTime2 != null) {
            recEndTime = tmpDataTime2.getTime();
            if (recEndTime < recStartTime) {
                WebParameterUtils.buildFailResult(sBuffer,
                        String.format("Parameter %s value must >= %s",
                                WebFieldDef.ENDTIME.name, WebFieldDef.RECORDTIME.name));
                return;
            }
        }
        // get the topic set to be set
        if (!WebParameterUtils.getStringParamValue(req,
                WebFieldDef.COMPSTOPICNAME, false, null, sBuffer, result)) {
            WebParameterUtils.buildFailResult(sBuffer, result.getErrMsg());
            return;
        }
        Set<String> topicSet = (Set<String>) result.getRetData();
        // get the maximum query turns
        if (!WebParameterUtils.getIntParamValue(req,
                WebFieldDef.MAXRETRYCOUNT, false,
                50, 1, 100, sBuffer, result)) {
            WebParameterUtils.buildFailResult(sBuffer, result.getErrMsg());
            return;
        }
        final int maxRetryCnt = (Integer) result.getRetData();
        // check storage status
        if (ServiceStatusHolder.isReadServiceStop()) {
            WebParameterUtils.buildFailResult(sBuffer,
                    "Read StoreService temporary unavailable!");
            return;
        }
        // get offset history storage
        MessageStore msgStore;
        MessageStoreManager storeManager = broker.getStoreManager();
        try {
            msgStore = storeManager.getOrCreateMessageStore(
                    TServerConstants.OFFSET_HISTORY_NAME, 0);
        } catch (Throwable ex) {
            WebParameterUtils.buildFailResult(sBuffer,
                    String.format("Get offset history store fail, reason=%s", ex.getMessage()));
            return;
        }
        // get the history offset in the time range
        long requestOffset = msgStore.getStartOffsetByTimeStamp(recStartTime);
        if (!getStoredGroupHisOffsets(groupName, topicSet, msgStore,
                requestOffset, maxRetryCnt, recStartTime, recEndTime, result)) {
            WebParameterUtils.buildFailResult(sBuffer, result.getErrMsg());
            return;
        }
        List<Tuple4<Long, String, Integer, Long>> resetOffsets =
                (List<Tuple4<Long, String, Integer, Long>>) result.getRetData();
        if (resetOffsets.isEmpty()) {
            WebParameterUtils.buildFailResult(sBuffer, "Not found history offset value!");
            return;
        }
        Set<String> groupNameSet = new HashSet<>();
        groupNameSet.add(groupName);
        // before
        Map<String, Map<String, Map<Integer, GroupOffsetInfo>>> befGroupOffsetMap =
                getGroupOffsetInfo(WebFieldDef.COMPSGROUPNAME, groupNameSet, topicSet);
        Map<String, Map<Integer, GroupOffsetInfo>> befTopicPartMap =
                befGroupOffsetMap.get(groupName);
        // change
        broker.getOffsetManager().modifyGroupOffset2(groupNameSet, resetOffsets, modifyUser);
        // after
        Map<String, Map<String, Map<Integer, GroupOffsetInfo>>> aftGroupOffsetMap =
                getGroupOffsetInfo(WebFieldDef.COMPSGROUPNAME, groupNameSet, topicSet);
        final Map<String, Map<Integer, GroupOffsetInfo>> aftTopicPartMap =
                aftGroupOffsetMap.get(groupName);
        // build result
        buildGroupOffsetUpdateResult(groupName, sBuffer, befTopicPartMap, aftTopicPartMap);
    }
Add or Modify consumer group offset by group's history offset time.

@param req      request
@param sBuffer  process result
inlong-tubemq/tubemq-server/src/main/java/org/apache/inlong/tubemq/server/broker/web/BrokerAdminServlet.java