From 30ea0060a57433fc2ecbf133f7015fa3a02dbf20 Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Sun, 25 Feb 2024 20:59:14 +0800 Subject: [PATCH 1/6] =?UTF-8?q?[feature]=20=E6=B7=BB=E5=8A=A0=E9=95=BF?= =?UTF-8?q?=E5=AE=89=E5=8D=81=E4=BA=8C=E6=97=B6=E8=BE=B0=E4=B8=8E=E7=8E=B0?= =?UTF-8?q?=E4=BB=A3=E6=97=B6=E9=97=B4=E7=9A=84=E4=BA=92=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../date/chinese/ChangAnTimeConverter.java | 67 +++++++++++++++++++ .../chinese/ChangAnTimeConverterTest.java | 38 +++++++++++ 2 files changed, 105 insertions(+) create mode 100644 hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverter.java create mode 100644 hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverterTest.java diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverter.java new file mode 100644 index 000000000..7505c8263 --- /dev/null +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverter.java @@ -0,0 +1,67 @@ +package org.dromara.hutool.core.date.chinese; + +import org.dromara.hutool.core.date.DateBetween; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * ChangAnTimeConverter + * + * @author achao@hutool.cn + */ +public class ChangAnTimeConverter { + + private static final Map timeMap = new HashMap<>(); + + static { + // 初始化时辰对应的小时范围 + timeMap.put("子", new int[]{23, 1}); + timeMap.put("丑", new int[]{1, 3}); + timeMap.put("寅", new int[]{3, 5}); + timeMap.put("卯", new int[]{5, 7}); + timeMap.put("辰", new int[]{7, 9}); + timeMap.put("巳", new int[]{9, 11}); + timeMap.put("午", new int[]{11, 13}); + timeMap.put("未", new int[]{13, 15}); + timeMap.put("申", new int[]{15, 17}); + timeMap.put("酉", new int[]{17, 19}); + timeMap.put("戌", new int[]{19, 21}); + timeMap.put("亥", new int[]{21, 23}); + } + + public static DateBetween toModernTime(String changAnTime) { + String time = changAnTime.replace("时", ""); + int[] hours = timeMap.get(time); + if (hours == null) { + throw new IllegalArgumentException("Invalid ChangAn time"); + } + + LocalDateTime now = LocalDateTime.now(); + LocalDateTime start = now.withHour(hours[0]).withMinute(0).withSecond(0).withNano(0); + LocalDateTime end = now.withHour(hours[1]).withMinute(0).withSecond(0).withNano(0); + if (hours[0] >= hours[1]) { + end = end.plusDays(1); // 处理跨日情况 + } + + Date startDate = Date.from(start.atZone(ZoneId.systemDefault()).toInstant()); + Date endDate = Date.from(end.atZone(ZoneId.systemDefault()).toInstant()); + + return DateBetween.of(startDate, endDate); + } + + public static String toChangAnTime(int hour) { + for (Map.Entry entry : timeMap.entrySet()) { + int startHour = entry.getValue()[0]; + int endHour = entry.getValue()[1]; + if (hour == 23 || hour == 0 || (hour >= startHour && hour < endHour) || (startHour > endHour && hour < endHour)) { + return entry.getKey() + "时"; + } + } + return "未知时"; + } + +} diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverterTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverterTest.java new file mode 100644 index 000000000..d14d81099 --- /dev/null +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverterTest.java @@ -0,0 +1,38 @@ +package org.dromara.hutool.core.date.chinese; + +import org.dromara.hutool.core.date.DateBetween; +import org.dromara.hutool.core.date.DateUnit; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * ChangAnTimeConverterTest + * + * @author achao@apache.org + */ +public class ChangAnTimeConverterTest { + + @Test + void testToModernTimeForAllTimes() { + // 测试每个时辰的转换 + String[] times = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}; + int[] expectedHours = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; + for (int i = 0; i < times.length; i++) { + DateBetween dateBetween = ChangAnTimeConverter.toModernTime(times[i] + "时"); + long hoursBetween = dateBetween.between(DateUnit.HOUR); + Assertions.assertEquals(expectedHours[i], hoursBetween, times[i] + "时 should last for 2 hours."); + } + } + + @Test + void testToChangAnTimeForAllHours() { + // 从23时开始测试,因为子时开始于23时 + String[] expectedTimes = {"子时", "丑时", "丑时", "寅时", "寅时", "卯时", "卯时", "辰时", "辰时", "巳时", "巳时", "午时", "午时", "未时", "未时", "申时", "申时", "酉时", "酉时", "戌时", "戌时", "亥时", "亥时", "子时"}; + for (int hour = 0; hour < 24; hour++) { + String expectedTime = expectedTimes[hour]; + String actualTime = ChangAnTimeConverter.toChangAnTime(hour); + Assertions.assertEquals(expectedTime, actualTime, "Hour " + hour + " should be in " + expectedTime); + } + } + +} From b9cf5e48c7770aa586fe70300996fa07057a1a20 Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Sun, 25 Feb 2024 21:29:09 +0800 Subject: [PATCH 2/6] =?UTF-8?q?[improve]=20=E5=AE=8C=E5=96=84=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=E5=92=8C=E4=BC=98=E5=8C=96=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dromara/hutool/core/date/DateBetween.java | 8 ++++ .../date/chinese/ChangAnTimeConverter.java | 38 +++++++++++++++++-- .../chinese/ChangAnTimeConverterTest.java | 13 ++++--- 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateBetween.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateBetween.java index b5114482d..e78e42253 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateBetween.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateBetween.java @@ -168,6 +168,14 @@ public class DateBetween implements Serializable { return result; } + public Date getBegin() { + return begin; + } + + public Date getEnd() { + return end; + } + /** * 格式化输出时间差 * diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverter.java index 7505c8263..2ae8e8590 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverter.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverter.java @@ -9,8 +9,22 @@ import java.util.HashMap; import java.util.Map; /** - * ChangAnTimeConverter - * + * 长安时辰转换器 + *

+ * 23-1 -> 子时 + * 1-3 -> 丑时 + * 3-5 -> 寅时 + * 5-7 -> 卯时 + * 7-9 -> 辰时 + * 9-11 -> 巳时 + * 11-13 -> 午时 + * 13-15 -> 未时 + * 15-17 -> 申时 + * 17-19 -> 酉时 + * 19-21 -> 戌时 + * 21-23 -> 亥时 + * 24/-1/其他值 -> 未知 + *

* @author achao@hutool.cn */ public class ChangAnTimeConverter { @@ -33,6 +47,16 @@ public class ChangAnTimeConverter { timeMap.put("亥", new int[]{21, 23}); } + /** + * 将长安时辰转换为现代时间 + *

+ * toModernTime("子时").getBegin().getHours() -> 23 + * toModernTime("子时").getEnd().getHours() -> 1 + *

+ * + * @param changAnTime 长安时辰 + * @return 现代时间段 + */ public static DateBetween toModernTime(String changAnTime) { String time = changAnTime.replace("时", ""); int[] hours = timeMap.get(time); @@ -53,6 +77,14 @@ public class ChangAnTimeConverter { return DateBetween.of(startDate, endDate); } + /** + * 将小时转换为长安时辰 + *

+ * toChangAnTime(1) -> "子时" + *

+ * @param hour 小时 + * @return 长安时辰 + */ public static String toChangAnTime(int hour) { for (Map.Entry entry : timeMap.entrySet()) { int startHour = entry.getValue()[0]; @@ -61,7 +93,7 @@ public class ChangAnTimeConverter { return entry.getKey() + "时"; } } - return "未知时"; + return "未知"; } } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverterTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverterTest.java index d14d81099..1dda622ad 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverterTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverterTest.java @@ -16,22 +16,23 @@ public class ChangAnTimeConverterTest { void testToModernTimeForAllTimes() { // 测试每个时辰的转换 String[] times = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}; - int[] expectedHours = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; + int[][] expectedHours = {{23, 1}, {1, 3}, {3, 5}, {5, 7}, {7, 9}, {9, 11}, {11, 13}, {13, 15}, {15, 17}, {17, 19}, {19, 21}, {21, 23}}; for (int i = 0; i < times.length; i++) { DateBetween dateBetween = ChangAnTimeConverter.toModernTime(times[i] + "时"); - long hoursBetween = dateBetween.between(DateUnit.HOUR); - Assertions.assertEquals(expectedHours[i], hoursBetween, times[i] + "时 should last for 2 hours."); + Assertions.assertEquals(2, dateBetween.between(DateUnit.HOUR)); + Assertions.assertEquals(expectedHours[i][0], dateBetween.getBegin().getHours()); + Assertions.assertEquals(expectedHours[i][1], dateBetween.getEnd().getHours()); } } @Test void testToChangAnTimeForAllHours() { // 从23时开始测试,因为子时开始于23时 - String[] expectedTimes = {"子时", "丑时", "丑时", "寅时", "寅时", "卯时", "卯时", "辰时", "辰时", "巳时", "巳时", "午时", "午时", "未时", "未时", "申时", "申时", "酉时", "酉时", "戌时", "戌时", "亥时", "亥时", "子时"}; - for (int hour = 0; hour < 24; hour++) { + String[] expectedTimes = {"子时", "丑时", "丑时", "寅时", "寅时", "卯时", "卯时", "辰时", "辰时", "巳时", "巳时", "午时", "午时", "未时", "未时", "申时", "申时", "酉时", "酉时", "戌时", "戌时", "亥时", "亥时", "子时", "未知"}; + for (int hour = 0; hour <= 24; hour++) { String expectedTime = expectedTimes[hour]; String actualTime = ChangAnTimeConverter.toChangAnTime(hour); - Assertions.assertEquals(expectedTime, actualTime, "Hour " + hour + " should be in " + expectedTime); + Assertions.assertEquals(expectedTime, actualTime); } } From 182ada0c113c3980adc7f7e7eab72200775a9cae Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Mon, 26 Feb 2024 22:27:47 +0800 Subject: [PATCH 3/6] [improve] update name to ShiChen --- .../chinese/{ChangAnTimeConverter.java => ShiChen.java} | 4 ++-- .../{ChangAnTimeConverterTest.java => ShiChenTest.java} | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) rename hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/{ChangAnTimeConverter.java => ShiChen.java} (97%) rename hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/{ChangAnTimeConverterTest.java => ShiChenTest.java} (86%) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ShiChen.java similarity index 97% rename from hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverter.java rename to hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ShiChen.java index 2ae8e8590..79f58d334 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverter.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ShiChen.java @@ -9,7 +9,7 @@ import java.util.HashMap; import java.util.Map; /** - * 长安时辰转换器 + * 时辰转换器 *

* 23-1 -> 子时 * 1-3 -> 丑时 @@ -27,7 +27,7 @@ import java.util.Map; *

* @author achao@hutool.cn */ -public class ChangAnTimeConverter { +public class ShiChen { private static final Map timeMap = new HashMap<>(); diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverterTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ShiChenTest.java similarity index 86% rename from hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverterTest.java rename to hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ShiChenTest.java index 1dda622ad..ebff657dd 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ChangAnTimeConverterTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ShiChenTest.java @@ -6,11 +6,11 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; /** - * ChangAnTimeConverterTest + * ShiChenTest * * @author achao@apache.org */ -public class ChangAnTimeConverterTest { +public class ShiChenTest { @Test void testToModernTimeForAllTimes() { @@ -18,7 +18,7 @@ public class ChangAnTimeConverterTest { String[] times = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}; int[][] expectedHours = {{23, 1}, {1, 3}, {3, 5}, {5, 7}, {7, 9}, {9, 11}, {11, 13}, {13, 15}, {15, 17}, {17, 19}, {19, 21}, {21, 23}}; for (int i = 0; i < times.length; i++) { - DateBetween dateBetween = ChangAnTimeConverter.toModernTime(times[i] + "时"); + DateBetween dateBetween = ShiChen.toModernTime(times[i] + "时"); Assertions.assertEquals(2, dateBetween.between(DateUnit.HOUR)); Assertions.assertEquals(expectedHours[i][0], dateBetween.getBegin().getHours()); Assertions.assertEquals(expectedHours[i][1], dateBetween.getEnd().getHours()); @@ -31,7 +31,7 @@ public class ChangAnTimeConverterTest { String[] expectedTimes = {"子时", "丑时", "丑时", "寅时", "寅时", "卯时", "卯时", "辰时", "辰时", "巳时", "巳时", "午时", "午时", "未时", "未时", "申时", "申时", "酉时", "酉时", "戌时", "戌时", "亥时", "亥时", "子时", "未知"}; for (int hour = 0; hour <= 24; hour++) { String expectedTime = expectedTimes[hour]; - String actualTime = ChangAnTimeConverter.toChangAnTime(hour); + String actualTime = ShiChen.toChangAnTime(hour); Assertions.assertEquals(expectedTime, actualTime); } } From 0e4fa575742230b617c4fcf877baba5f9bc25352 Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Tue, 27 Feb 2024 01:19:47 +0800 Subject: [PATCH 4/6] =?UTF-8?q?[improve]=20=E6=94=AF=E6=8C=81=20=E5=AE=8B?= =?UTF-8?q?=E4=BB=A5=E5=90=8E=E6=8A=8A=E5=8D=81=E4=BA=8C=E6=97=B6=E8=BE=B0?= =?UTF-8?q?=E4=B8=AD=E6=AF=8F=E4=B8=AA=E6=97=B6=E8=BE=B0=E5=B9=B3=E5=88=86?= =?UTF-8?q?=E4=B8=BA=E5=88=9D=E3=80=81=E6=AD=A3=E4=B8=A4=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hutool/core/date/chinese/ShiChen.java | 133 +++++++++--------- .../hutool/core/date/chinese/ShiChenTest.java | 54 ++++--- 2 files changed, 105 insertions(+), 82 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ShiChen.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ShiChen.java index 79f58d334..a94584dc0 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ShiChen.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ShiChen.java @@ -1,6 +1,7 @@ package org.dromara.hutool.core.date.chinese; import org.dromara.hutool.core.date.DateBetween; +import org.dromara.hutool.core.text.StrUtil; import java.time.LocalDateTime; import java.time.ZoneId; @@ -9,67 +10,80 @@ import java.util.HashMap; import java.util.Map; /** - * 时辰转换器 + * 时辰转换器,支持宋以后的二十四时辰制度。 *

- * 23-1 -> 子时 - * 1-3 -> 丑时 - * 3-5 -> 寅时 - * 5-7 -> 卯时 - * 7-9 -> 辰时 - * 9-11 -> 巳时 - * 11-13 -> 午时 - * 13-15 -> 未时 - * 15-17 -> 申时 - * 17-19 -> 酉时 - * 19-21 -> 戌时 - * 21-23 -> 亥时 - * 24/-1/其他值 -> 未知 - *

+ * 该转换器能够处理包含“时”、“初”或“正”后缀的长安时辰描述,并根据这些描述自动返回相应的现代时间段。 + * 对于“初”和“正”的描述,分别对应每个时辰的前半段和后半段,而不带后缀的时辰描述则表示该时辰的整个时间段。 + *

+ *

+ * 此外,该转换器还提供了根据小时数转换为对应的长安时辰描述的功能,通过isAbs参数可以控制返回的描述是否包含“初”或“正”。 + *

+ *

+ * 示例: + *

    + *
  • toModernTime("子时") 返回的时间段从23点开始到1点结束。
  • + *
  • toModernTime("子初") 返回的时间段从23点开始到0点结束。
  • + *
  • toModernTime("子正") 返回的时间段从0点开始到1点结束。
  • + *
  • toShiChen(0, false) 返回“子正”。
  • + *
  • toShiChen(0, true) 返回“子时”。
  • + *
+ *

* @author achao@hutool.cn */ public class ShiChen { - private static final Map timeMap = new HashMap<>(); + private static final Map timeMap = new HashMap<>(); + private static final Map fullTimeMap = new HashMap<>(); + private static final Map hourToShiChenMap = new HashMap<>(); + private static final Map hourToShiChenAbsMap = new HashMap<>(); static { // 初始化时辰对应的小时范围 - timeMap.put("子", new int[]{23, 1}); - timeMap.put("丑", new int[]{1, 3}); - timeMap.put("寅", new int[]{3, 5}); - timeMap.put("卯", new int[]{5, 7}); - timeMap.put("辰", new int[]{7, 9}); - timeMap.put("巳", new int[]{9, 11}); - timeMap.put("午", new int[]{11, 13}); - timeMap.put("未", new int[]{13, 15}); - timeMap.put("申", new int[]{15, 17}); - timeMap.put("酉", new int[]{17, 19}); - timeMap.put("戌", new int[]{19, 21}); - timeMap.put("亥", new int[]{21, 23}); + String[] times = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}; + int hour = 23; + for (String time : times) { + timeMap.put(time + "初", hour % 24); + timeMap.put(time + "正", (hour + 1) % 24); + fullTimeMap.put(time, new Integer[]{hour % 24, (hour + 2) % 24}); + hour += 2; + } + + // 初始化小时到时辰的映射 + hour = 23; + for (String time : times) { + hourToShiChenMap.put(hour % 24, time + "初"); + hourToShiChenMap.put((hour + 1) % 24, time + "正"); + hourToShiChenAbsMap.put(hour % 24, time + "时"); + hourToShiChenAbsMap.put((hour + 1) % 24, time + "时"); + hour += 2; + } } - /** - * 将长安时辰转换为现代时间 - *

- * toModernTime("子时").getBegin().getHours() -> 23 - * toModernTime("子时").getEnd().getHours() -> 1 - *

- * - * @param changAnTime 长安时辰 - * @return 现代时间段 - */ - public static DateBetween toModernTime(String changAnTime) { - String time = changAnTime.replace("时", ""); - int[] hours = timeMap.get(time); - if (hours == null) { - throw new IllegalArgumentException("Invalid ChangAn time"); + public static DateBetween toModernTime(String shiChen) { + if (StrUtil.isEmpty(shiChen)) { + throw new IllegalArgumentException("Invalid shiChen"); + } + Integer startHour, endHour; + LocalDateTime start, end; + + if (shiChen.endsWith("初") || shiChen.endsWith("正")) { + startHour = timeMap.get(shiChen); + if (startHour == null) { + throw new IllegalArgumentException("Invalid ChangAn time"); + } + endHour = (startHour + 1) % 24; + } else { + String baseTime = shiChen.replace("时", ""); + Integer[] hours = fullTimeMap.get(baseTime); + if (hours == null) { + throw new IllegalArgumentException("Invalid ChangAn time"); + } + startHour = hours[0]; + endHour = hours[1]; } - LocalDateTime now = LocalDateTime.now(); - LocalDateTime start = now.withHour(hours[0]).withMinute(0).withSecond(0).withNano(0); - LocalDateTime end = now.withHour(hours[1]).withMinute(0).withSecond(0).withNano(0); - if (hours[0] >= hours[1]) { - end = end.plusDays(1); // 处理跨日情况 - } + start = LocalDateTime.now().withHour(startHour).withMinute(0).withSecond(0).withNano(0); + end = (startHour > endHour) ? start.plusDays(1).withHour(endHour) : start.withHour(endHour); Date startDate = Date.from(start.atZone(ZoneId.systemDefault()).toInstant()); Date endDate = Date.from(end.atZone(ZoneId.systemDefault()).toInstant()); @@ -77,23 +91,12 @@ public class ShiChen { return DateBetween.of(startDate, endDate); } - /** - * 将小时转换为长安时辰 - *

- * toChangAnTime(1) -> "子时" - *

- * @param hour 小时 - * @return 长安时辰 - */ - public static String toChangAnTime(int hour) { - for (Map.Entry entry : timeMap.entrySet()) { - int startHour = entry.getValue()[0]; - int endHour = entry.getValue()[1]; - if (hour == 23 || hour == 0 || (hour >= startHour && hour < endHour) || (startHour > endHour && hour < endHour)) { - return entry.getKey() + "时"; - } + public static String toShiChen(int hour, boolean isAbs) { + String result = hourToShiChenAbsMap.getOrDefault(hour, "未知"); + if (!isAbs && !result.equals("未知")) { + result = hourToShiChenMap.get(hour); } - return "未知"; + return result; } } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ShiChenTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ShiChenTest.java index ebff657dd..ebc723b20 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ShiChenTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ShiChenTest.java @@ -1,6 +1,5 @@ package org.dromara.hutool.core.date.chinese; -import org.dromara.hutool.core.date.DateBetween; import org.dromara.hutool.core.date.DateUnit; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -13,27 +12,48 @@ import org.junit.jupiter.api.Test; public class ShiChenTest { @Test - void testToModernTimeForAllTimes() { - // 测试每个时辰的转换 + void testToModernTime() { + // 测试“时”后缀的转换,表示整个时辰 + Assertions.assertEquals(2, ShiChen.toModernTime("子时").between(DateUnit.HOUR)); + + // 测试“初”和“正”后缀的转换,表示时辰的前半段和后半段 + Assertions.assertEquals(1, ShiChen.toModernTime("子初").between(DateUnit.HOUR)); + Assertions.assertEquals(1, ShiChen.toModernTime("子正").between(DateUnit.HOUR)); + + // 测试所有时辰 String[] times = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}; - int[][] expectedHours = {{23, 1}, {1, 3}, {3, 5}, {5, 7}, {7, 9}, {9, 11}, {11, 13}, {13, 15}, {15, 17}, {17, 19}, {19, 21}, {21, 23}}; - for (int i = 0; i < times.length; i++) { - DateBetween dateBetween = ShiChen.toModernTime(times[i] + "时"); - Assertions.assertEquals(2, dateBetween.between(DateUnit.HOUR)); - Assertions.assertEquals(expectedHours[i][0], dateBetween.getBegin().getHours()); - Assertions.assertEquals(expectedHours[i][1], dateBetween.getEnd().getHours()); + for (String time : times) { + Assertions.assertEquals(2, ShiChen.toModernTime(time + "时").between(DateUnit.HOUR)); + Assertions.assertEquals(1, ShiChen.toModernTime(time + "初").between(DateUnit.HOUR)); + Assertions.assertEquals(1, ShiChen.toModernTime(time + "正").between(DateUnit.HOUR)); } + Assertions.assertThrows(IllegalArgumentException.class, () -> { + ShiChen.toModernTime("无效时"); + }); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + ShiChen.toModernTime("无效正"); + }); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + ShiChen.toModernTime(""); + }); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + ShiChen.toModernTime(null); + }); } @Test - void testToChangAnTimeForAllHours() { - // 从23时开始测试,因为子时开始于23时 - String[] expectedTimes = {"子时", "丑时", "丑时", "寅时", "寅时", "卯时", "卯时", "辰时", "辰时", "巳时", "巳时", "午时", "午时", "未时", "未时", "申时", "申时", "酉时", "酉时", "戌时", "戌时", "亥时", "亥时", "子时", "未知"}; - for (int hour = 0; hour <= 24; hour++) { - String expectedTime = expectedTimes[hour]; - String actualTime = ShiChen.toChangAnTime(hour); - Assertions.assertEquals(expectedTime, actualTime); - } + void testToShiChen() { + // 测试小时转换为长安时辰,不包含“初”或“正” + Assertions.assertEquals("子时", ShiChen.toShiChen(23, true)); + Assertions.assertEquals("子时", ShiChen.toShiChen(0, true)); + + // 测试小时转换为长安时辰,包含“初”或“正” + Assertions.assertEquals("子正", ShiChen.toShiChen(0, false)); + Assertions.assertEquals("丑初", ShiChen.toShiChen(1, false)); + + // 测试边界条件 + Assertions.assertEquals("未知", ShiChen.toShiChen(24, true)); + Assertions.assertEquals("未知", ShiChen.toShiChen(-1, false)); } } From 2f2076b1ea5bd6096dd07d132227896a9126370b Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Tue, 27 Feb 2024 01:20:50 +0800 Subject: [PATCH 5/6] [improve] code format --- .../hutool/core/date/chinese/ShiChenTest.java | 44 ++++++++----------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ShiChenTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ShiChenTest.java index ebc723b20..7e950b417 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ShiChenTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/chinese/ShiChenTest.java @@ -1,9 +1,11 @@ package org.dromara.hutool.core.date.chinese; import org.dromara.hutool.core.date.DateUnit; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + /** * ShiChenTest * @@ -14,46 +16,38 @@ public class ShiChenTest { @Test void testToModernTime() { // 测试“时”后缀的转换,表示整个时辰 - Assertions.assertEquals(2, ShiChen.toModernTime("子时").between(DateUnit.HOUR)); + assertEquals(2, ShiChen.toModernTime("子时").between(DateUnit.HOUR)); // 测试“初”和“正”后缀的转换,表示时辰的前半段和后半段 - Assertions.assertEquals(1, ShiChen.toModernTime("子初").between(DateUnit.HOUR)); - Assertions.assertEquals(1, ShiChen.toModernTime("子正").between(DateUnit.HOUR)); + assertEquals(1, ShiChen.toModernTime("子初").between(DateUnit.HOUR)); + assertEquals(1, ShiChen.toModernTime("子正").between(DateUnit.HOUR)); // 测试所有时辰 String[] times = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}; for (String time : times) { - Assertions.assertEquals(2, ShiChen.toModernTime(time + "时").between(DateUnit.HOUR)); - Assertions.assertEquals(1, ShiChen.toModernTime(time + "初").between(DateUnit.HOUR)); - Assertions.assertEquals(1, ShiChen.toModernTime(time + "正").between(DateUnit.HOUR)); + assertEquals(2, ShiChen.toModernTime(time + "时").between(DateUnit.HOUR)); + assertEquals(1, ShiChen.toModernTime(time + "初").between(DateUnit.HOUR)); + assertEquals(1, ShiChen.toModernTime(time + "正").between(DateUnit.HOUR)); } - Assertions.assertThrows(IllegalArgumentException.class, () -> { - ShiChen.toModernTime("无效时"); - }); - Assertions.assertThrows(IllegalArgumentException.class, () -> { - ShiChen.toModernTime("无效正"); - }); - Assertions.assertThrows(IllegalArgumentException.class, () -> { - ShiChen.toModernTime(""); - }); - Assertions.assertThrows(IllegalArgumentException.class, () -> { - ShiChen.toModernTime(null); - }); + assertThrows(IllegalArgumentException.class, () -> ShiChen.toModernTime("无效时")); + assertThrows(IllegalArgumentException.class, () -> ShiChen.toModernTime("无效正")); + assertThrows(IllegalArgumentException.class, () -> ShiChen.toModernTime("")); + assertThrows(IllegalArgumentException.class, () -> ShiChen.toModernTime(null)); } @Test void testToShiChen() { // 测试小时转换为长安时辰,不包含“初”或“正” - Assertions.assertEquals("子时", ShiChen.toShiChen(23, true)); - Assertions.assertEquals("子时", ShiChen.toShiChen(0, true)); + assertEquals("子时", ShiChen.toShiChen(23, true)); + assertEquals("子时", ShiChen.toShiChen(0, true)); // 测试小时转换为长安时辰,包含“初”或“正” - Assertions.assertEquals("子正", ShiChen.toShiChen(0, false)); - Assertions.assertEquals("丑初", ShiChen.toShiChen(1, false)); + assertEquals("子正", ShiChen.toShiChen(0, false)); + assertEquals("丑初", ShiChen.toShiChen(1, false)); // 测试边界条件 - Assertions.assertEquals("未知", ShiChen.toShiChen(24, true)); - Assertions.assertEquals("未知", ShiChen.toShiChen(-1, false)); + assertEquals("未知", ShiChen.toShiChen(24, true)); + assertEquals("未知", ShiChen.toShiChen(-1, false)); } } From 6b4d2791552b8c44137d1a05a38b4d85c288aa2b Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Tue, 27 Feb 2024 01:28:38 +0800 Subject: [PATCH 6/6] =?UTF-8?q?[improve]=20=E4=BC=98=E5=8C=96=E3=80=81?= =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hutool/core/date/chinese/ShiChen.java | 55 ++++++++++++++++--- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ShiChen.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ShiChen.java index a94584dc0..799ac571f 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ShiChen.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/chinese/ShiChen.java @@ -11,23 +11,31 @@ import java.util.Map; /** * 时辰转换器,支持宋以后的二十四时辰制度。 - *

- * 该转换器能够处理包含“时”、“初”或“正”后缀的长安时辰描述,并根据这些描述自动返回相应的现代时间段。 - * 对于“初”和“正”的描述,分别对应每个时辰的前半段和后半段,而不带后缀的时辰描述则表示该时辰的整个时间段。 + *

本转换器提供以下功能: + *

    + *
  • 处理包含“时”、“初”或“正”后缀的长安时辰描述,并自动返回相应的现代时间段。 + * “初”和“正”分别对应每个时辰的前半段和后半段,而不带后缀的“时”描述则涵盖该时辰的完整时间段。
  • + *
  • 根据小时数转换为相应的长安时辰描述,通过{@code isAbs}参数控制是否包含“初”或“正”。
  • + *
*

*

- * 此外,该转换器还提供了根据小时数转换为对应的长安时辰描述的功能,通过isAbs参数可以控制返回的描述是否包含“初”或“正”。 + * 异常情况: + *

    + *
  • 如果输入的长安时辰描述无效或不被识别,{@code toModernTime} 方法将抛出 {@code IllegalArgumentException}。
  • + *
  • 同样,如果{@code toShiChen}方法接收到无效的小时数,将返回“未知”。
  • + *
*

*

* 示例: *

    - *
  • toModernTime("子时") 返回的时间段从23点开始到1点结束。
  • - *
  • toModernTime("子初") 返回的时间段从23点开始到0点结束。
  • - *
  • toModernTime("子正") 返回的时间段从0点开始到1点结束。
  • - *
  • toShiChen(0, false) 返回“子正”。
  • - *
  • toShiChen(0, true) 返回“子时”。
  • + *
  • {@code toModernTime("子时")} 返回的时间段从23点开始到1点结束。
  • + *
  • {@code toModernTime("子初")} 返回的时间段从23点开始到0点结束。
  • + *
  • {@code toModernTime("子正")} 返回的时间段从0点开始到1点结束。
  • + *
  • {@code toShiChen(0, false)} 返回“子正”。
  • + *
  • {@code toShiChen(0, true)} 返回“子时”。
  • *
*

+ * * @author achao@hutool.cn */ public class ShiChen { @@ -59,6 +67,21 @@ public class ShiChen { } } + /** + * 将长安时辰描述转换为现代时间段。 + *

+ * 示例: + *

    + *
  • {@code toModernTime("子时")} 返回的时间段从23点开始到1点结束。
  • + *
  • {@code toModernTime("子初")} 返回的时间段从23点开始到0点结束。
  • + *
  • {@code toModernTime("子正")} 返回的时间段从0点开始到1点结束。
  • + *
+ *

+ * + * @param shiChen 长安时辰描述,可以是“时”、“初”或“正”结尾。 + * @return {@link DateBetween} 对象,表示起始和结束时间。 + * @throws IllegalArgumentException 如果输入的长安时辰描述无效。 + */ public static DateBetween toModernTime(String shiChen) { if (StrUtil.isEmpty(shiChen)) { throw new IllegalArgumentException("Invalid shiChen"); @@ -91,6 +114,20 @@ public class ShiChen { return DateBetween.of(startDate, endDate); } + /** + * 根据给定的小时数转换为对应的长安时辰描述。 + *

+ * 示例: + *

    + *
  • {@code toShiChen(0, false)} 返回“子正”。
  • + *
  • {@code toShiChen(0, true)} 返回“子时”。
  • + *
+ *

+ * + * @param hour 小时数,应在0到23之间。 + * @param isAbs 是否返回绝对时辰描述(即包含“时”后缀),而不是“初”或“正”。 + * @return 长安时辰描述,如果小时数无效,则返回“未知”。 + */ public static String toShiChen(int hour, boolean isAbs) { String result = hourToShiChenAbsMap.getOrDefault(hour, "未知"); if (!isAbs && !result.equals("未知")) {