diff --git a/hutool-core/src/main/java/cn/hutool/core/date/Month.java b/hutool-core/src/main/java/cn/hutool/core/date/Month.java
index ca8a347ce..95d71c083 100644
--- a/hutool-core/src/main/java/cn/hutool/core/date/Month.java
+++ b/hutool-core/src/main/java/cn/hutool/core/date/Month.java
@@ -174,11 +174,12 @@ public enum Month {
* 解析别名为Month对象,别名如:jan或者JANUARY,不区分大小写
*
* @param name 别名值
- * @return 月份int值
+ * @return 月份枚举Month,非空
* @throws IllegalArgumentException 如果别名无对应的枚举,抛出此异常
* @since 5.8.0
*/
public static Month of(String name) throws IllegalArgumentException {
+ Assert.notBlank(name);
Month of = of(ArrayUtil.indexOfIgnoreCase(ALIASES, name));
if (null == of) {
of = Month.valueOf(name.toUpperCase());
@@ -186,6 +187,16 @@ public enum Month {
return of;
}
+ /**
+ * {@link java.time.Month}转换为Month对象
+ * @param month {@link java.time.Month}
+ * @return Month
+ * @since 5.8.0
+ */
+ public static Month of(java.time.Month month){
+ return of(month.ordinal());
+ }
+
/**
* 获得指定月的最后一天
*
diff --git a/hutool-core/src/main/java/cn/hutool/core/date/Week.java b/hutool-core/src/main/java/cn/hutool/core/date/Week.java
index 7fd20abae..afffe7b0c 100644
--- a/hutool-core/src/main/java/cn/hutool/core/date/Week.java
+++ b/hutool-core/src/main/java/cn/hutool/core/date/Week.java
@@ -1,5 +1,6 @@
package cn.hutool.core.date;
+import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ArrayUtil;
import java.time.DayOfWeek;
@@ -165,11 +166,12 @@ public enum Week {
* 解析别名为Week对象,别名如:sun或者SUNDAY,不区分大小写
*
* @param name 别名值
- * @return 周int值
+ * @return 周枚举Week,非空
* @throws IllegalArgumentException 如果别名无对应的枚举,抛出此异常
* @since 5.8.0
*/
public static Week of(String name) throws IllegalArgumentException {
+ Assert.notBlank(name);
Week of = of(ArrayUtil.indexOfIgnoreCase(ALIASES, name));
if (null == of) {
of = Week.valueOf(name.toUpperCase());
@@ -192,8 +194,9 @@ public enum Week {
* @since 5.7.14
*/
public static Week of(DayOfWeek dayOfWeek) {
- int week = dayOfWeek.ordinal() + 2;
- if (week > 7) {
+ Assert.notNull(dayOfWeek);
+ int week = dayOfWeek.ordinal() + 1;
+ if (7 == week) {
week = 1;
}
return of(week);
diff --git a/hutool-core/src/test/java/cn/hutool/core/date/MonthTest.java b/hutool-core/src/test/java/cn/hutool/core/date/MonthTest.java
index 6f8d4f8fd..3700ea6d3 100644
--- a/hutool-core/src/test/java/cn/hutool/core/date/MonthTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/date/MonthTest.java
@@ -51,16 +51,19 @@ public class MonthTest {
@Test
public void ofTest(){
- Month jan = Month.of("Jan");
- Assert.assertEquals(Month.JANUARY, jan);
+ Month month = Month.of("Jan");
+ Assert.assertEquals(Month.JANUARY, month);
- jan = Month.of("JAN");
- Assert.assertEquals(Month.JANUARY, jan);
+ month = Month.of("JAN");
+ Assert.assertEquals(Month.JANUARY, month);
- jan = Month.of("FEBRUARY");
- Assert.assertEquals(Month.FEBRUARY, jan);
+ month = Month.of("FEBRUARY");
+ Assert.assertEquals(Month.FEBRUARY, month);
- jan = Month.of("February");
- Assert.assertEquals(Month.FEBRUARY, jan);
+ month = Month.of("February");
+ Assert.assertEquals(Month.FEBRUARY, month);
+
+ month = Month.of(java.time.Month.FEBRUARY);
+ Assert.assertEquals(Month.FEBRUARY, month);
}
}
diff --git a/hutool-core/src/test/java/cn/hutool/core/date/WeekTest.java b/hutool-core/src/test/java/cn/hutool/core/date/WeekTest.java
index 3eb9d3f86..944232e7a 100644
--- a/hutool-core/src/test/java/cn/hutool/core/date/WeekTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/date/WeekTest.java
@@ -37,6 +37,16 @@ public class WeekTest {
Assert.assertEquals(Week.SATURDAY, Week.of("SATURDAY"));
}
+ public void ofTest2(){
+ Assert.assertEquals(Week.SUNDAY, Week.of(DayOfWeek.SUNDAY));
+ Assert.assertEquals(Week.MONDAY, Week.of(DayOfWeek.MONDAY));
+ Assert.assertEquals(Week.TUESDAY, Week.of(DayOfWeek.TUESDAY));
+ Assert.assertEquals(Week.WEDNESDAY, Week.of(DayOfWeek.WEDNESDAY));
+ Assert.assertEquals(Week.THURSDAY, Week.of(DayOfWeek.THURSDAY));
+ Assert.assertEquals(Week.FRIDAY, Week.of(DayOfWeek.FRIDAY));
+ Assert.assertEquals(Week.SATURDAY, Week.of(DayOfWeek.SATURDAY));
+ }
+
@Test
public void toJdkDayOfWeekTest(){
Assert.assertEquals(DayOfWeek.MONDAY, Week.MONDAY.toJdkDayOfWeek());
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/CronConfig.java b/hutool-cron/src/main/java/cn/hutool/cron/CronConfig.java
index 4e8812eb3..516ed8de5 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/CronConfig.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/CronConfig.java
@@ -45,7 +45,7 @@ public class CronConfig {
/**
* 是否支持秒匹配
*
- * @return true
使用,false
不使用
+ * @return {@code true}使用,{@code false}不使用
*/
public boolean isMatchSecond() {
return this.matchSecond;
@@ -54,7 +54,7 @@ public class CronConfig {
/**
* 设置是否支持秒匹配,默认不使用
*
- * @param isMatchSecond true
支持,false
不支持
+ * @param isMatchSecond {@code true}支持,{@code false}不支持
* @return this
*/
public CronConfig setMatchSecond(boolean isMatchSecond) {
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/Part.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/Part.java
index 5cfd5435a..fcbf0b4a6 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/Part.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/Part.java
@@ -6,8 +6,13 @@ import cn.hutool.core.lang.Assert;
import cn.hutool.cron.CronException;
/**
- * 表达式各个部分的枚举,用于限定位置和规则
- * {@link #ordinal()}表示此部分在表达式中的位置,如0表示秒
+ * 表达式各个部分的枚举,用于限定在表达式中的位置和规则(如最小值和最大值)
+ * {@link #ordinal()}表示此部分在表达式中的位置,如0表示秒
+ * 表达式各个部分的枚举位置为:
+ *
+ * 0 1 2 3 4 5 6
+ * [SECOND] MINUTE HOUR DAY_OF_MONTH MONTH DAY_OF_WEEK [YEAR]
+ *
*
* @author looly
* @since 5.8.0
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/YearValueMatcher.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/YearValueMatcher.java
index 2a6ad6cc0..58bc6a7da 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/YearValueMatcher.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/YearValueMatcher.java
@@ -1,19 +1,20 @@
package cn.hutool.cron.pattern.matcher;
-import java.util.List;
+import java.util.Collection;
+import java.util.LinkedHashSet;
/**
* 年匹配
- * 考虑年数字太大,不适合boolean数组,单独使用列表遍历匹配
- * @author Looly
+ * 考虑年数字太大,不适合boolean数组,单独使用{@link LinkedHashSet}匹配
*
+ * @author Looly
*/
-public class YearValueMatcher implements ValueMatcher{
+public class YearValueMatcher implements ValueMatcher {
- private final List valueList;
+ private final LinkedHashSet valueList;
- public YearValueMatcher(List intValueList) {
- this.valueList = intValueList;
+ public YearValueMatcher(Collection intValueList) {
+ this.valueList = new LinkedHashSet<>(intValueList);
}
@Override
@@ -24,7 +25,7 @@ public class YearValueMatcher implements ValueMatcher{
@Override
public int nextAfter(int value) {
for (Integer year : valueList) {
- if(year >= value){
+ if (year >= value) {
return year;
}
}
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/PartParser.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/PartParser.java
index 0972aab65..6a2341abd 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/PartParser.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/PartParser.java
@@ -3,7 +3,6 @@ package cn.hutool.cron.pattern.parser;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.Month;
import cn.hutool.core.date.Week;
-import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.cron.CronException;
@@ -18,7 +17,18 @@ import java.util.ArrayList;
import java.util.List;
/**
- * 定时任务表达式各个部分的解析器
+ * 定时任务表达式各个部分的解析器,根据{@link Part}指定不同部分,解析为{@link ValueMatcher}
+ * 每个部分支持:
+ *
+ * - * :表示匹配这个位置所有的时间
+ * - ? :表示匹配这个位置任意的时间(与"*"作用一致)
+ * - L :表示匹配这个位置允许的最大值
+ * - */2 :表示间隔时间,例如在分上,表示每两分钟,同样*可以使用数字列表代替,逗号分隔
+ * - 2-8 :表示连续区间,例如在分上,表示2,3,4,5,6,7,8分
+ * - 2,3,5,8 :表示列表
+ * - wed :表示周别名
+ * - jan :表示月别名
+ *
*
* @author looly
* @since 5.8.0
@@ -46,7 +56,13 @@ public class PartParser {
}
/**
- * 将表达式解析为{@link ValueMatcher}
+ * 将表达式解析为{@link ValueMatcher}
+ *
+ * - * 或者 ? 返回{@link AlwaysTrueValueMatcher}
+ * - {@link Part#DAY_OF_MONTH} 返回{@link DayOfMonthValueMatcher}
+ * - {@link Part#YEAR} 返回{@link YearValueMatcher}
+ * - 其他 返回{@link BoolArrayValueMatcher}
+ *
*
* @param value 表达式
* @return {@link ValueMatcher}
@@ -220,11 +236,6 @@ public class PartParser {
* @throws CronException 当无效数字或无效别名时抛出
*/
private int parseNumber(String value) throws CronException {
- if ("L".equalsIgnoreCase(value)) {
- // L表示最大值
- return part.getMax();
- }
-
int i;
try {
i = Integer.parseInt(value);
@@ -233,7 +244,7 @@ public class PartParser {
}
// 周日可以用0或7表示,统一转换为0
- if(this.part == Part.DAY_OF_WEEK && Week.SUNDAY.getIso8601Value() == i){
+ if(Part.DAY_OF_WEEK.equals(this.part) && Week.SUNDAY.getIso8601Value() == i){
i = Week.SUNDAY.ordinal();
}
@@ -241,24 +252,29 @@ public class PartParser {
}
/**
- * 解析别名,只支持{@link Part#MONTH}和{@link Part#DAY_OF_WEEK}
+ * 解析别名支持包括:
+ *
+ * - L 表示最大值
+ * - {@link Part#MONTH}和{@link Part#DAY_OF_WEEK}别名
+ *
*
* @param name 别名
* @return 解析int值
* @throws CronException 无匹配别名时抛出异常
*/
private int parseAlias(String name) throws CronException {
+ if ("L".equalsIgnoreCase(name)) {
+ // L表示最大值
+ return part.getMax();
+ }
+
switch (this.part) {
case MONTH:
- final Month month = Month.of(name);
- Assert.notNull(month, () -> new CronException("Invalid month alias: {}", name));
// 月份从1开始
- return month.getValueBaseOne();
+ return Month.of(name).getValueBaseOne();
case DAY_OF_WEEK:
- final Week week = Week.of(name);
- Assert.notNull(week, () -> new CronException("Invalid day of week alias: {}", name));
// 周从0开始,0表示周日
- return week.ordinal();
+ return Week.of(name).ordinal();
}
throw new CronException("Invalid alias value: [{}]", name);
diff --git a/hutool-cron/src/test/java/cn/hutool/cron/pattern/CronPatternTest.java b/hutool-cron/src/test/java/cn/hutool/cron/pattern/CronPatternTest.java
index b2367b74b..51e34921a 100644
--- a/hutool-cron/src/test/java/cn/hutool/cron/pattern/CronPatternTest.java
+++ b/hutool-cron/src/test/java/cn/hutool/cron/pattern/CronPatternTest.java
@@ -1,7 +1,6 @@
package cn.hutool.cron.pattern;
import cn.hutool.core.date.DateUtil;
-import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.cron.CronException;
import org.junit.Assert;
import org.junit.Test;
@@ -17,22 +16,21 @@ public class CronPatternTest {
public void matchAllTest() {
CronPattern pattern;
// 任何时间匹配
- pattern = new CronPattern("* * * * * *");
- ThreadUtil.sleep(600);
- Assert.assertTrue(pattern.match(DateUtil.current(), true));
- Assert.assertTrue(pattern.match(DateUtil.current(), false));
+ pattern = CronPattern.of("* * * * * *");
+ assertMatch(pattern, DateUtil.now());
}
@Test
public void matchAllTest2() {
- // 在5位表达式中,秒部分并不是任意匹配,而是一个固定值
+ // 在5位表达式中,秒部分并不是任意匹配,而是一个固定值0
// 因此此处匹配就不能匹配秒
CronPattern pattern;
// 任何时间匹配
- pattern = new CronPattern("* * * * *");
- for (int i = 0; i < 1; i++) {
- Assert.assertTrue(pattern.match(DateUtil.current(), false));
- }
+ // 分 时 天 月 周
+ pattern = CronPattern.of("* * * * *");
+
+ // 测试时,秒归零,则任意时间匹配
+ assertMatch(pattern, DateUtil.beginOfMinute(DateUtil.date()).toString());
}
@Test
@@ -40,11 +38,11 @@ public class CronPatternTest {
CronPattern pattern;
// 12:11匹配
- pattern = new CronPattern("39 11 12 * * *");
+ pattern = CronPattern.of("39 11 12 * * *");
assertMatch(pattern, "12:11:39");
// 每5分钟匹配,匹配分钟为:[0,5,10,15,20,25,30,35,40,45,50,55]
- pattern = new CronPattern("39 */5 * * * *");
+ pattern = CronPattern.of("39 */5 * * * *");
assertMatch(pattern, "12:00:39");
assertMatch(pattern, "12:05:39");
assertMatch(pattern, "12:10:39");
@@ -59,28 +57,28 @@ public class CronPatternTest {
assertMatch(pattern, "12:55:39");
// 2:01,3:01,4:01
- pattern = new CronPattern("39 1 2-4 * * *");
+ pattern = CronPattern.of("39 1 2-4 * * *");
assertMatch(pattern, "02:01:39");
assertMatch(pattern, "03:01:39");
assertMatch(pattern, "04:01:39");
// 2:01,3:01,4:01
- pattern = new CronPattern("39 1 2,3,4 * * *");
+ pattern = CronPattern.of("39 1 2,3,4 * * *");
assertMatch(pattern, "02:01:39");
assertMatch(pattern, "03:01:39");
assertMatch(pattern, "04:01:39");
// 08-07, 08-06
- pattern = new CronPattern("39 0 0 6,7 8 *");
+ pattern = CronPattern.of("39 0 0 6,7 8 *");
assertMatch(pattern, "2016-08-07 00:00:39");
assertMatch(pattern, "2016-08-06 00:00:39");
// 别名忽略大小写
- pattern = new CronPattern("39 0 0 6,7 Aug *");
+ pattern = CronPattern.of("39 0 0 6,7 Aug *");
assertMatch(pattern, "2016-08-06 00:00:39");
assertMatch(pattern, "2016-08-07 00:00:39");
- pattern = new CronPattern("39 0 0 7 aug *");
+ pattern = CronPattern.of("39 0 0 7 aug *");
assertMatch(pattern, "2016-08-07 00:00:39");
}
@@ -104,34 +102,34 @@ public class CronPatternTest {
@SuppressWarnings("ConstantConditions")
@Test
public void CronPatternTest2() {
- CronPattern pattern = new CronPattern("0/30 * * * *");
+ CronPattern pattern = CronPattern.of("0/30 * * * *");
Assert.assertTrue(pattern.match(DateUtil.parse("2018-10-09 12:00:00").getTime(), false));
Assert.assertTrue(pattern.match(DateUtil.parse("2018-10-09 12:30:00").getTime(), false));
- pattern = new CronPattern("32 * * * *");
+ pattern = CronPattern.of("32 * * * *");
Assert.assertTrue(pattern.match(DateUtil.parse("2018-10-09 12:32:00").getTime(), false));
}
@Test
public void patternTest() {
- CronPattern pattern = new CronPattern("* 0 4 * * ?");
+ CronPattern pattern = CronPattern.of("* 0 4 * * ?");
assertMatch(pattern, "2017-02-09 04:00:00");
assertMatch(pattern, "2017-02-19 04:00:33");
// 6位Quartz风格表达式
- pattern = new CronPattern("* 0 4 * * ?");
+ pattern = CronPattern.of("* 0 4 * * ?");
assertMatch(pattern, "2017-02-09 04:00:00");
assertMatch(pattern, "2017-02-19 04:00:33");
}
@Test
public void rangePatternTest() {
- CronPattern pattern = new CronPattern("* 20/2 * * * ?");
+ CronPattern pattern = CronPattern.of("* 20/2 * * * ?");
assertMatch(pattern, "2017-02-09 04:20:00");
assertMatch(pattern, "2017-02-09 05:20:00");
assertMatch(pattern, "2017-02-19 04:22:33");
- pattern = new CronPattern("* 2-20/2 * * * ?");
+ pattern = CronPattern.of("* 2-20/2 * * * ?");
assertMatch(pattern, "2017-02-09 04:02:00");
assertMatch(pattern, "2017-02-09 05:04:00");
assertMatch(pattern, "2017-02-19 04:20:33");
@@ -140,23 +138,23 @@ public class CronPatternTest {
@Test
public void lastTest() {
// 每月最后一天的任意时间
- CronPattern pattern = new CronPattern("* * * L * ?");
+ CronPattern pattern = CronPattern.of("* * * L * ?");
assertMatch(pattern, "2017-07-31 04:20:00");
assertMatch(pattern, "2017-02-28 04:20:00");
// 最后一个月的任意时间
- pattern = new CronPattern("* * * * L ?");
+ pattern = CronPattern.of("* * * * L ?");
assertMatch(pattern, "2017-12-02 04:20:00");
// 任意天的最后时间
- pattern = new CronPattern("L L L * * ?");
+ pattern = CronPattern.of("L L L * * ?");
assertMatch(pattern, "2017-12-02 23:59:59");
}
@Test(expected = CronException.class)
public void rangeYearTest() {
// year的范围是1970~2099年,超出报错
- new CronPattern("0/1 * * * 1/1 ? 2020-2120");
+ CronPattern.of("0/1 * * * 1/1 ? 2020-2120");
}
/**