public static String addTime(String dateStr, LocalTime time,
            IntervalInfo intervalInfo, boolean isPositive) {
        int factor = intervalInfo.getFactor();
        Map<ChronoField, Long> valueMap = intervalInfo.getChronoMap();
        boolean hasMicroSecond = dateStr.indexOf('.') != -1;

        int sign = isPositive ? 1 : -1;

        for (ChronoField field : valueMap.keySet()) {
            long amount = valueMap.get(field) * factor * sign;
            switch (field) {
                case MICRO_OF_SECOND:
                    hasMicroSecond = true;
                    time = time.plusNanos(amount * 1000L);
                    break;
                case SECOND_OF_MINUTE:
                    time = time.plusSeconds(amount);
                    break;
                case MINUTE_OF_HOUR:
                    time = time.plusMinutes(amount);
                    break;
                case HOUR_OF_DAY:
                    time = time.plusHours(amount);
                    break;
                default:
                    return null;
            }
        }

        if (hasMicroSecond) {
            return time.format(TIME_FORMATTER_MAP.get(HOUR_TO_MICRO));
        } else {
            return time.format(TIME_FORMATTER_MAP.get(HOUR_TO_SECOND));
        }
    }
@param dateStr The first time string
@param time It is obtained by parsing dateStr
@param intervalInfo addend
@param isPositive   True is positive, false is negative
@return
inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/utils/DateUtil.java