不贫便是富,不爱购置便是收入。——西塞罗

[v6] [feature] 添加长安十二时辰与现代时间的互转 · Pull Request !1184 · dromara/hutool - Gitee.com

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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;

/**
* 长安时辰转换器
* <p>
* 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/其他值 -> 未知
* </p>
* @author achao@hutool.cn
*/
public class ChangAnTimeConverter {

private static final Map<String, int[]> 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});
}

/**
* 将长安时辰转换为现代时间
* <p>
* toModernTime("子时").getBegin().getHours() -> 23
* toModernTime("子时").getEnd().getHours() -> 1
* </p>
*
* @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");
}

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);
}

/**
* 将小时转换为长安时辰
* <p>
* toChangAnTime(1) -> "子时"
*</p>
* @param hour 小时
* @return 长安时辰
*/
public static String toChangAnTime(int hour) {
for (Map.Entry<String, int[]> 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 "未知";
}

}

使用如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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 = {{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] + "时");
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 expectedTime = expectedTimes[hour];
String actualTime = ChangAnTimeConverter.toChangAnTime(hour);
Assertions.assertEquals(expectedTime, actualTime);
}
}

}