Bladeren bron

feat: support DailyTimeInterval #558

tjq 2 jaren geleden
bovenliggende
commit
9f2f68344c

+ 4 - 2
powerjob-common/src/main/java/tech/powerjob/common/enums/TimeExpressionType.java

@@ -23,7 +23,9 @@ public enum TimeExpressionType {
     CRON(2),
     FIXED_RATE(3),
     FIXED_DELAY(4),
-    WORKFLOW(5);
+    WORKFLOW(5),
+
+    DAILY_TIME_INTERVAL(11);
 
     private final int v;
 
@@ -31,7 +33,7 @@ public enum TimeExpressionType {
     /**
      * 首次计算触发时间时必须计算出一个有效值
      */
-    public static final List<Integer> INSPECT_TYPES =  Collections.unmodifiableList(Lists.newArrayList(CRON.v));
+    public static final List<Integer> INSPECT_TYPES =  Collections.unmodifiableList(Lists.newArrayList(CRON.v, DAILY_TIME_INTERVAL.v));
 
     public static TimeExpressionType of(int v) {
         for (TimeExpressionType type : values()) {

+ 238 - 0
powerjob-server/powerjob-server-core/src/main/java/tech/powerjob/server/core/scheduler/auxiliary/TimeOfDay.java

@@ -0,0 +1,238 @@
+package tech.powerjob.server.core.scheduler.auxiliary;
+
+import java.io.Serializable;
+
+
+import java.io.Serializable;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+ * Represents a time in hour, minute and second of any given day.
+ *
+ * <p>The hour is in 24-hour convention, meaning values are from 0 to 23.</p>
+ * <a href="https://github.com/quartz-scheduler/quartz">PowerJob learn from quartz</a>
+ *
+ * @since 2.0.3
+ *
+ * @author James House
+ * @author Zemian Deng <saltnlight5@gmail.com>
+ */
+public class TimeOfDay implements Serializable {
+
+    private static final long serialVersionUID = 2964774315889061771L;
+
+    private final int hour;
+    private final int minute;
+    private final int second;
+
+    /**
+     * Create a TimeOfDay instance for the given hour, minute and second.
+     *
+     * @param hour The hour of day, between 0 and 23.
+     * @param minute The minute of the hour, between 0 and 59.
+     * @param second The second of the minute, between 0 and 59.
+     * @throws IllegalArgumentException if one or more of the input values is out of their valid range.
+     */
+    public TimeOfDay(int hour, int minute, int second) {
+        this.hour = hour;
+        this.minute = minute;
+        this.second = second;
+        validate();
+    }
+
+    /**
+     * Create a TimeOfDay instance for the given hour and minute (at the zero second of the minute).
+     *
+     * @param hour The hour of day, between 0 and 23.
+     * @param minute The minute of the hour, between 0 and 59.
+     * @throws IllegalArgumentException if one or more of the input values is out of their valid range.
+     */
+    public TimeOfDay(int hour, int minute) {
+        this.hour = hour;
+        this.minute = minute;
+        this.second = 0;
+        validate();
+    }
+
+    private void validate() {
+        if(hour < 0 || hour > 23)
+            throw new IllegalArgumentException("Hour must be from 0 to 23");
+        if(minute < 0 || minute > 59)
+            throw new IllegalArgumentException("Minute must be from 0 to 59");
+        if(second < 0 || second > 59)
+            throw new IllegalArgumentException("Second must be from 0 to 59");
+    }
+
+    /**
+     * Create a TimeOfDay instance for the given hour, minute and second.
+     *
+     * @param hour The hour of day, between 0 and 23.
+     * @param minute The minute of the hour, between 0 and 59.
+     * @param second The second of the minute, between 0 and 59.
+     * @throws IllegalArgumentException if one or more of the input values is out of their valid range.
+     */
+    public static TimeOfDay hourMinuteAndSecondOfDay(int hour, int minute, int second) {
+        return new TimeOfDay(hour, minute, second);
+    }
+
+    /**
+     * Create a TimeOfDay instance for the given hour and minute (at the zero second of the minute).
+     *
+     * @param hour The hour of day, between 0 and 23.
+     * @param minute The minute of the hour, between 0 and 59.
+     * @throws IllegalArgumentException if one or more of the input values is out of their valid range.
+     */
+    public static TimeOfDay hourAndMinuteOfDay(int hour, int minute) {
+        return new TimeOfDay(hour, minute);
+    }
+
+    /**
+     * The hour of the day (between 0 and 23).
+     *
+     * @return The hour of the day (between 0 and 23).
+     */
+    public int getHour() {
+        return hour;
+    }
+
+    /**
+     * The minute of the hour.
+     *
+     * @return The minute of the hour (between 0 and 59).
+     */
+    public int getMinute() {
+        return minute;
+    }
+
+    /**
+     * The second of the minute.
+     *
+     * @return The second of the minute (between 0 and 59).
+     */
+    public int getSecond() {
+        return second;
+    }
+
+    /**
+     * Determine with this time of day is before the given time of day.
+     *
+     * @return true this time of day is before the given time of day.
+     */
+    public boolean before(TimeOfDay timeOfDay) {
+
+        if(timeOfDay.hour > hour)
+            return true;
+        if(timeOfDay.hour < hour)
+            return false;
+
+        if(timeOfDay.minute > minute)
+            return true;
+        if(timeOfDay.minute < minute)
+            return false;
+
+        if(timeOfDay.second > second)
+            return true;
+        if(timeOfDay.second < second)
+            return false;
+
+        return false; // must be equal...
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if(!(obj instanceof TimeOfDay))
+            return false;
+
+        TimeOfDay other = (TimeOfDay)obj;
+
+        return (other.hour == hour && other.minute == minute && other.second == second);
+    }
+
+    @Override
+    public int hashCode() {
+        return (hour + 1) ^ (minute + 1) ^ (second + 1);
+    }
+
+    /** Return a date with time of day reset to this object values. The millisecond value will be zero. */
+    public Date getTimeOfDayForDate(Date dateTime) {
+        if (dateTime == null)
+            return null;
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(dateTime);
+        cal.set(Calendar.HOUR_OF_DAY, hour);
+        cal.set(Calendar.MINUTE, minute);
+        cal.set(Calendar.SECOND, second);
+        cal.clear(Calendar.MILLISECOND);
+        return cal.getTime();
+    }
+
+    /**
+     * Create a TimeOfDay from the given date, in the system default TimeZone.
+     *
+     * @param dateTime The java.util.Date from which to extract Hour, Minute and Second.
+     */
+    public static TimeOfDay hourAndMinuteAndSecondFromDate(Date dateTime) {
+        return hourAndMinuteAndSecondFromDate(dateTime, null);
+    }
+
+    /**
+     * Create a TimeOfDay from the given date, in the given TimeZone.
+     *
+     * @param dateTime The java.util.Date from which to extract Hour, Minute and Second.
+     * @param tz The TimeZone from which relate Hour, Minute and Second for the given date.  If null, system default
+     * TimeZone will be used.
+     */
+    public static TimeOfDay hourAndMinuteAndSecondFromDate(Date dateTime, TimeZone tz) {
+        if (dateTime == null)
+            return null;
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(dateTime);
+        if(tz != null)
+            cal.setTimeZone(tz);
+
+        return new TimeOfDay(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
+    }
+
+    /**
+     * Create a TimeOfDay from the given date (at the zero-second), in the system default TimeZone.
+     *
+     * @param dateTime The java.util.Date from which to extract Hour and Minute.
+     */
+    public static TimeOfDay hourAndMinuteFromDate(Date dateTime) {
+        return hourAndMinuteFromDate(dateTime, null);
+    }
+
+    /**
+     * Create a TimeOfDay from the given date (at the zero-second), in the system default TimeZone.
+     *
+     * @param dateTime The java.util.Date from which to extract Hour and Minute.
+     * @param tz The TimeZone from which relate Hour and Minute for the given date.  If null, system default
+     * TimeZone will be used.
+     */
+    public static TimeOfDay hourAndMinuteFromDate(Date dateTime, TimeZone tz) {
+        if (dateTime == null)
+            return null;
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(dateTime);
+        if(tz != null)
+            cal.setTimeZone(tz);
+
+        return new TimeOfDay(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE));
+    }
+
+    public static TimeOfDay from(String hms) {
+        String[] split = hms.split(":");
+        if (split.length != 3) {
+            throw new IllegalArgumentException("invalid TimeOfDay, make pattern like 15:30:10");
+        }
+        return new TimeOfDay(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]));
+    }
+
+    @Override
+    public String toString() {
+        return "TimeOfDay[" + hour + ":" + minute + ":" + second + "]";
+    }
+}
+

+ 78 - 0
powerjob-server/powerjob-server-core/src/main/java/tech/powerjob/server/core/scheduler/auxiliary/impl/DailyTimeIntervalStrategyHandler.java

@@ -0,0 +1,78 @@
+package tech.powerjob.server.core.scheduler.auxiliary.impl;
+
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.SneakyThrows;
+import org.apache.commons.lang3.time.DateUtils;
+import tech.powerjob.common.OmsConstant;
+import tech.powerjob.common.enums.TimeExpressionType;
+import tech.powerjob.common.serialize.JsonUtils;
+import tech.powerjob.common.utils.CommonUtils;
+import tech.powerjob.server.core.scheduler.auxiliary.TimeOfDay;
+import tech.powerjob.server.core.scheduler.auxiliary.TimingStrategyHandler;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * DailyTimeIntervalStrategyHandler
+ * @author 550w
+ * @date 2027/02/15
+ */
+public class DailyTimeIntervalStrategyHandler implements TimingStrategyHandler {
+
+    @Override
+    public TimeExpressionType supportType() {
+        return TimeExpressionType.DAILY_TIME_INTERVAL;
+    }
+
+    @Override
+    @SneakyThrows
+    public void validate(String timeExpression) {
+        DailyTimeIntervalExpress ep = JsonUtils.parseObject(timeExpression, DailyTimeIntervalExpress.class);
+        CommonUtils.requireNonNull(ep.interval, "interval can't be null or empty in DailyTimeIntervalExpress");
+        CommonUtils.requireNonNull(ep.startTimeOfDay, "startTimeOfDay can't be null or empty in DailyTimeIntervalExpress");
+        CommonUtils.requireNonNull(ep.endTimeOfDay, "endTimeOfDay can't be null or empty in DailyTimeIntervalExpress");
+
+        TimeOfDay startTime = TimeOfDay.from(ep.startTimeOfDay);
+        TimeOfDay endTime = TimeOfDay.from(ep.endTimeOfDay);
+        if (endTime.before(startTime)) {
+            throw new IllegalArgumentException("endTime should after startTime!");
+        }
+    }
+
+    @Override
+    public Long calculateNextTriggerTime(Long preTriggerTime, String timeExpression, Long startTime, Long endTime) {
+
+        return null;
+    }
+
+    @Data
+    static class DailyTimeIntervalExpress implements Serializable {
+
+        /**
+         * 时间间隔
+         */
+        private Long interval;
+        /**
+         * 每天激活的时间起点,格式为:18:30:00 代表 18点30分00秒激活
+         */
+        private String startTimeOfDay;
+        /**
+         * 每日激活的时间终点,格式同上
+         */
+        private String endTimeOfDay;
+
+        /* ************ 非必填字段 ************ */
+        /**
+         * 时间单位,默认秒
+         */
+        private String intervalUnit;
+        /**
+         * 每周的哪几天激活,空代表每天都激活
+         */
+        private Set<Integer> daysOfWeek;
+    }
+}