From 0c6bd4e7dc94ec45be64d23e91b4bc859aed3ccb Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 27 Oct 2020 10:41:24 +0800 Subject: [PATCH] add method --- CHANGELOG.md | 1 + .../java/cn/hutool/core/date/ChineseDate.java | 38 +++++--------- .../cn/hutool/core/date/chinese/GanZhi.java | 50 +++++++++++++++++++ .../hutool/core/date/chinese/LunarInfo.java | 7 +++ .../cn/hutool/core/text/csv/CsvWriter.java | 24 ++++----- .../cn/hutool/core/date/ChineseDateTest.java | 23 --------- .../cn/hutool/core/date/DateUtilTest.java | 13 ++++- .../java/cn/hutool/core/date/GanzhiTest.java | 45 +++++++++++++++++ 8 files changed, 139 insertions(+), 62 deletions(-) create mode 100644 hutool-core/src/test/java/cn/hutool/core/date/GanzhiTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fa159d29..08f48f250 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### 新特性 * 【core 】 增加OptionalBean(pr#1182@Github) +* 【core 】 Ganzhi增加方法(issue#1186@Github) ### Bug修复 ------------------------------------------------------------------------------------------------------------- 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 e6166d318..473238375 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 @@ -5,7 +5,6 @@ import cn.hutool.core.date.chinese.ChineseMonth; import cn.hutool.core.date.chinese.GanZhi; import cn.hutool.core.date.chinese.LunarFestival; import cn.hutool.core.date.chinese.LunarInfo; -import cn.hutool.core.date.chinese.SolarTerms; import cn.hutool.core.util.StrUtil; import java.util.Date; @@ -18,11 +17,6 @@ import java.util.Date; * @since 5.1.1 */ public class ChineseDate { - /** - * 1900-01-31 - */ -// private static final long BASE_DATE = -2206425943000L; - private static final long BASE_DAY = -25538; //农历年 private final int year; @@ -48,7 +42,7 @@ public class ChineseDate { */ public ChineseDate(Date date) { // 求出和1900年1月31日相差的天数 - int offset = (int) ((DateUtil.beginOfDay(date).getTime() / DateUnit.DAY.getMillis()) - BASE_DAY); + int offset = (int) ((DateUtil.beginOfDay(date).getTime() / DateUnit.DAY.getMillis()) - LunarInfo.BASE_DAY); // 计算农历年份 // 用offset减去每农历年的天数,计算当天是农历第几天,offset是当年的第几天 int daysOfYear; @@ -245,12 +239,12 @@ public class ChineseDate { /** - * 获得天干地支 + * 获得年的天干地支 * * @return 获得天干地支 */ public String getCyclical() { - return GanZhi.cyclicalm(year - LunarInfo.BASE_YEAR + 36); + return GanZhi.getGanzhiOfYear(this.year); } /** @@ -260,7 +254,7 @@ public class ChineseDate { */ public String getCyclicalYMD() { if (gyear >= LunarInfo.BASE_YEAR && gmonth > 0 && gday > 0) { - return (cyclicalm(gyear, gmonth, gday)); + return cyclicalm(gyear, gmonth, gday); } return null; } @@ -285,24 +279,16 @@ public class ChineseDate { /** * 这里同步处理年月日的天干地支信息 * - * @param Y 年 - * @param M 月 - * @param D 日 + * @param year 公历年 + * @param month 公历月,从1开始 + * @param day 公历日 * @return 天干地支信息 */ - private String cyclicalm(int Y, int M, int D) { - String gzyear = GanZhi.cyclicalm(year - LunarInfo.BASE_YEAR + 36); - //天干地支处理 - //返回当月「节」为几日开始 - int firstNode = SolarTerms.getTerm(Y, (M * 2 - 1)); - // 依据12节气修正干支月 - String gzM = GanZhi.cyclicalm((Y - LunarInfo.BASE_YEAR) * 12 + M + 11); - if (D >= firstNode) { - gzM = GanZhi.cyclicalm((Y - LunarInfo.BASE_YEAR) * 12 + M + 12); - } - int dayCyclical = (int) ((DateUtil.parseDate(Y + "-" + M + "-" + "1").getTime() / DateUnit.DAY.getMillis() - BASE_DAY + 30)) + 10; - String gzD = GanZhi.cyclicalm(dayCyclical + D - 1); - return gzyear + "年" + gzM + "月" + gzD + "日"; + private String cyclicalm(int year, int month, int day) { + return StrUtil.format("{}年{}月{}日", + GanZhi.getGanzhiOfYear(this.year), + GanZhi.getGanzhiOfMonth(year, month, day), + GanZhi.getGanzhiOfDay(year, month, day)); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/date/chinese/GanZhi.java b/hutool-core/src/main/java/cn/hutool/core/date/chinese/GanZhi.java index 1404058f8..4ae9d5653 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/chinese/GanZhi.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/chinese/GanZhi.java @@ -1,5 +1,7 @@ package cn.hutool.core.date.chinese; +import java.time.LocalDate; + /** * 天干地支类 * @@ -20,4 +22,52 @@ public class GanZhi { public static String cyclicalm(int num) { return (GAN[num % 10] + ZHI[num % 12]); } + + /** + * 传入年传回干支 + * + * @param year 农历年 + * @return 干支 + * @since 5.4.7 + */ + public static String getGanzhiOfYear(int year) { + // 1864年(1900 - 36)是甲子年,用于计算基准的干支年 + return cyclicalm(year - LunarInfo.BASE_YEAR + 36); + } + + /** + * 获取干支月 + * + * @param year 公历年 + * @param month 公历月,从1开始 + * @param day 公历日 + * @return 干支月 + * @since 5.4.7 + */ + public static String getGanzhiOfMonth(int year, int month, int day) { + //返回当月「节」为几日开始 + int firstNode = SolarTerms.getTerm(year, (month * 2 - 1)); + // 依据12节气修正干支月 + int monthOffset = (year - LunarInfo.BASE_YEAR) * 12 + month + 11; + if(day >= firstNode){ + monthOffset++; + } + return cyclicalm(monthOffset); + } + + /** + * 获取干支日 + * + * @param year 公历年 + * @param month 公历月,从1开始 + * @param day 公历日 + * @return 干支 + * @since 5.4.7 + */ + public static String getGanzhiOfDay(int year, int month, int day) { + // 与1970-01-01相差天数,不包括当天 + final long days = LocalDate.of(year, month, day).toEpochDay() - 1; + //1899-12-21是农历1899年腊月甲子日 40:相差1900-01-31有40天 + return cyclicalm((int)(days - LunarInfo.BASE_DAY + 40)); + } } 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 12863a4b6..4f138ff0c 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 @@ -8,7 +8,14 @@ package cn.hutool.core.date.chinese; */ public class LunarInfo { + /** + * 1900年 + */ public static final int BASE_YEAR = 1900; + /** + * 1900-01-31 + */ + public static final long BASE_DAY = -25538; /** * 此表来自:https://github.com/jjonline/calendar.js/blob/master/calendar.js diff --git a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvWriter.java b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvWriter.java index bdbfbdf70..d9528bc26 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvWriter.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvWriter.java @@ -1,15 +1,5 @@ package cn.hutool.core.text.csv; -import java.io.BufferedWriter; -import java.io.Closeable; -import java.io.File; -import java.io.Flushable; -import java.io.IOException; -import java.io.Serializable; -import java.io.Writer; -import java.nio.charset.Charset; -import java.util.Collection; - import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.io.FileUtil; @@ -20,6 +10,16 @@ import cn.hutool.core.util.CharUtil; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.ObjectUtil; +import java.io.BufferedWriter; +import java.io.Closeable; +import java.io.File; +import java.io.Flushable; +import java.io.IOException; +import java.io.Serializable; +import java.io.Writer; +import java.nio.charset.Charset; +import java.util.Collection; + /** * CSV数据写出器 * @@ -249,8 +249,8 @@ public final class CsvWriter implements Closeable, Flushable, Serializable { */ private void doAppendLine(final String... fields) throws IOException { if (null != fields) { - for (int i = 0; i < fields.length; i++) { - appendField(fields[i]); + for (String field : fields) { + appendField(field); } writer.write(config.lineDelimiter); newline = true; 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 1792fd4ff..54c50dd37 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 @@ -46,29 +46,6 @@ public class ChineseDateTest { date = new ChineseDate(DateUtil.parseDate("1996-07-15")); Assert.assertEquals("丙子鼠年 五月三十", date.toString()); } - @Test - public void getCyclicalYMDTest(){ - //通过公历构建 - ChineseDate chineseDate = new ChineseDate(DateUtil.parseDate("1993-01-06")); - String cyclicalYMD = chineseDate.getCyclicalYMD(); - Assert.assertEquals("壬申年癸丑月丁亥日",cyclicalYMD); - } - - @Test - public void getCyclicalYMDTest2(){ - //通过农历构建 - ChineseDate chineseDate = new ChineseDate(1992,12,14); - String cyclicalYMD = chineseDate.getCyclicalYMD(); - Assert.assertEquals("壬申年癸丑月丁亥日",cyclicalYMD); - } - - @Test - public void getCyclicalYMDTest3(){ - //通过公历构建 - ChineseDate chineseDate = new ChineseDate(DateUtil.parseDate("2020-08-28")); - String cyclicalYMD = chineseDate.getCyclicalYMD(); - Assert.assertEquals("庚子年甲申月癸卯日",cyclicalYMD); - } @Test public void getChineseMonthTest(){ diff --git a/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java index 2ded43d89..ab68a122a 100644 --- a/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java @@ -3,7 +3,7 @@ package cn.hutool.core.date; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.BetweenFormater.Level; import cn.hutool.core.date.format.FastDateFormat; -import cn.hutool.core.lang.Console; +import cn.hutool.core.util.RandomUtil; import org.junit.Assert; import org.junit.Test; @@ -783,6 +783,17 @@ public class DateUtilTest { Assert.assertEquals(30L, weekCount); } + @Test + public void betweenDayTest() { + for (int i = 0; i < 1000; i++) { + String datr = RandomUtil.randomInt(1900, 2099) + "-01-20"; + long betweenDay = DateUtil.betweenDay( + DateUtil.parseDate("1970-01-01"), + DateUtil.parseDate(datr), false); + Assert.assertEquals(Math.abs(LocalDate.parse(datr).toEpochDay()), betweenDay); + } + } + @Test public void dayOfYearTest() { int dayOfYear = DateUtil.dayOfYear(DateUtil.parse("2020-01-01")); diff --git a/hutool-core/src/test/java/cn/hutool/core/date/GanzhiTest.java b/hutool-core/src/test/java/cn/hutool/core/date/GanzhiTest.java new file mode 100644 index 000000000..1f4abaa61 --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/date/GanzhiTest.java @@ -0,0 +1,45 @@ +package cn.hutool.core.date; + +import cn.hutool.core.date.chinese.GanZhi; +import org.junit.Assert; +import org.junit.Test; + +public class GanzhiTest { + + @Test + public void getGanzhiOfYearTest(){ + Assert.assertEquals("庚子", GanZhi.getGanzhiOfYear(2020)); + } + + @Test + public void getCyclicalYMDTest(){ + //通过公历构建 + ChineseDate chineseDate = new ChineseDate(DateUtil.parseDate("1993-01-06")); + String cyclicalYMD = chineseDate.getCyclicalYMD(); + Assert.assertEquals("壬申年癸丑月丁亥日",cyclicalYMD); + } + + @Test + public void getCyclicalYMDTest2(){ + //通过农历构建 + ChineseDate chineseDate = new ChineseDate(1992,12,14); + String cyclicalYMD = chineseDate.getCyclicalYMD(); + Assert.assertEquals("壬申年癸丑月丁亥日",cyclicalYMD); + } + + @Test + public void getCyclicalYMDTest3(){ + //通过公历构建 + ChineseDate chineseDate = new ChineseDate(DateUtil.parseDate("2020-08-28")); + String cyclicalYMD = chineseDate.getCyclicalYMD(); + Assert.assertEquals("庚子年甲申月癸卯日",cyclicalYMD); + } + + @Test + public void getCyclicalYMDTest4(){ + //通过公历构建 + ChineseDate chineseDate = new ChineseDate(DateUtil.parseDate("1905-08-28")); + String cyclicalYMD = chineseDate.getCyclicalYMD(); + Assert.assertEquals("乙巳年甲申月己亥日",cyclicalYMD); + } +}