Browse Source

add method

Looly 5 years ago
parent
commit
0c6bd4e7dc

+ 1 - 0
CHANGELOG.md

@@ -7,6 +7,7 @@
 
 ### 新特性
 * 【core   】     增加OptionalBean(pr#1182@Github)
+* 【core   】     Ganzhi增加方法(issue#1186@Github)
 ### Bug修复
 
 -------------------------------------------------------------------------------------------------------------

+ 12 - 26
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));
 	}
 
 	/**

+ 50 - 0
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));
+	}
 }

+ 7 - 0
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

+ 12 - 12
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;

+ 0 - 23
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(){

+ 12 - 1
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;
 
@@ -784,6 +784,17 @@ public class DateUtilTest {
 	}
 
 	@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"));
 		Assert.assertEquals(1, dayOfYear);

+ 45 - 0
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);
+	}
+}