diff --git a/CHANGELOG.md b/CHANGELOG.md index b21ded5a9..44dbfe5a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ * 【cache 】 修复ReentrantCache.toString方法线程不安全问题(issue#2140@Github) * 【core 】 修复SystemPropsUtil.getInt返回long问题(pr#546@Gitee) * 【crypto 】 修复SM2.getD前导0问题(pr#2149@Github) +* 【core 】 修复ChineseDate在1970年之前农历差一天问题(issue#I4UTPK@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.7.21 (2022-02-14) diff --git a/hutool-core/src/main/java/cn/hutool/core/date/CalendarUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/CalendarUtil.java index 91744046f..57f1f25c2 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/CalendarUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/CalendarUtil.java @@ -50,13 +50,25 @@ public class CalendarUtil { } /** - * 转换为Calendar对象 + * 转换为Calendar对象,使用当前默认时区 * * @param millis 时间戳 * @return Calendar对象 */ public static Calendar calendar(long millis) { - final Calendar cal = Calendar.getInstance(); + return calendar(millis, TimeZone.getDefault()); + } + + /** + * 转换为Calendar对象 + * + * @param millis 时间戳 + * @param timeZone 时区 + * @return Calendar对象 + * @since 5.7.22 + */ + public static Calendar calendar(long millis, TimeZone timeZone) { + final Calendar cal = Calendar.getInstance(timeZone); cal.setTimeInMillis(millis); return cal; } diff --git a/hutool-core/src/main/java/cn/hutool/core/date/ChineseDate.java b/hutool-core/src/main/java/cn/hutool/core/date/ChineseDate.java index 1dc0d2136..ffdda37e4 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/ChineseDate.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/ChineseDate.java @@ -50,11 +50,18 @@ public class ChineseDate { // 公历 final DateTime dt = DateUtil.beginOfDay(date); gyear = dt.year(); - gmonthBase1 = dt.month() + 1; + gmonthBase1 = dt.monthBaseOne(); gday = dt.dayOfMonth(); // 求出和1900年1月31日相差的天数 - int offset = (int) ((dt.getTime() / DateUnit.DAY.getMillis()) - LunarInfo.BASE_DAY); + final long time = dt.getTime(); + int offset = (int) ((time / DateUnit.DAY.getMillis()) - LunarInfo.BASE_DAY); + if(time > 0 && (time % DateUnit.DAY.getMillis()) > 0){ + // 在GMT+0800时区或非UTC时区,1970-01-02的时间戳小于一天的毫秒数,导致减法后为0,之后的农历总会少一天 + // 此处判断是否有余数,如果有则非UTC时间,此时将时间差算为一天。 + offset++; + } + // 计算农历年份 // 用offset减去每农历年的天数,计算当天是农历第几天,offset是当年的第几天 int daysOfYear; diff --git a/hutool-core/src/main/java/cn/hutool/core/date/chinese/LunarInfo.java b/hutool-core/src/main/java/cn/hutool/core/date/chinese/LunarInfo.java index d558c7a86..a4d72c14b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/chinese/LunarInfo.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/chinese/LunarInfo.java @@ -13,9 +13,9 @@ public class LunarInfo { */ public static final int BASE_YEAR = 1900; /** - * 1900-01-31 + * 1900-01-31,农历正月初一 */ - public static final long BASE_DAY = -25538; + public static final long BASE_DAY = -25537; /** * 此表来自:https://github.com/jjonline/calendar.js/blob/master/calendar.js diff --git a/hutool-core/src/test/java/cn/hutool/core/date/ChineseDateTest.java b/hutool-core/src/test/java/cn/hutool/core/date/ChineseDateTest.java index d75f01f59..20914552c 100644 --- a/hutool-core/src/test/java/cn/hutool/core/date/ChineseDateTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/date/ChineseDateTest.java @@ -1,6 +1,5 @@ package cn.hutool.core.date; -import cn.hutool.core.lang.Console; import cn.hutool.core.util.StrUtil; import org.junit.Assert; import org.junit.Test; @@ -118,10 +117,26 @@ public class ChineseDateTest { } @Test - public void dayTest(){ - Date date = DateUtil.parse("1900-01-31"); - //Date date = DateUtil.parse("2022-02-22","yyyy-MM-dd"); + public void day19700101Test(){ + // https://gitee.com/dromara/hutool/issues/I4UTPK + Date date = DateUtil.parse("1970-01-01"); ChineseDate chineseDate = new ChineseDate(date); - Console.log(chineseDate); + Assert.assertEquals("己酉鸡年 冬月廿四", chineseDate.toString()); + + date = DateUtil.parse("1970-01-02"); + chineseDate = new ChineseDate(date); + Assert.assertEquals("己酉鸡年 冬月廿五", chineseDate.toString()); + + date = DateUtil.parse("1970-01-03"); + chineseDate = new ChineseDate(date); + Assert.assertEquals("己酉鸡年 冬月廿六", chineseDate.toString()); + } + + @Test + public void day19000101Test(){ + // 1900-01-31之前不支持 + Date date = DateUtil.parse("1900-01-31"); + ChineseDate chineseDate = new ChineseDate(date); + Assert.assertEquals("庚子鼠年 正月初一", chineseDate.toString()); } }