add method

This commit is contained in:
Looly 2020-10-18 13:23:37 +08:00
parent 0085954326
commit d5192d8f61
9 changed files with 192 additions and 26 deletions

View File

@ -22,6 +22,7 @@
* 【core 】 Assert增加函数接口pr#1166@Github
* 【core 】 新增AtomicIntegerArray、AtomicLongArray转换
* 【extra 】 PinyinUtil新增Bopomofo4j支持
* 【core 】 新增TemporalUtil工具类新增时间相关方法
### Bug修复
* 【core 】 解决农历判断节日未判断大小月导致的问题issue#I1XHSF@Gitee
@ -30,6 +31,7 @@
* 【core 】 修复CaseInsensitiveMap的remove等方法并没有忽略大小写的问题pr#1163@Gitee
* 【poi 】 修复合并单元格值读取错误的问题
* 【poi 】 修复NamedSql解析形如col::numeric出错问题issue#I1YHBX@Gitee
* 【core 】 修复计算相差天数导致的问题
-------------------------------------------------------------------------------------------------------------

View File

@ -21,7 +21,9 @@ public class ChineseDate {
/**
* 1900-01-31
*/
private static final long BASE_DATE = -2206425943000L;
// private static final long BASE_DATE = -2206425943000L;
private static final long BASE_DAY = -25538;
//农历年
private final int year;
//农历月
@ -46,13 +48,12 @@ public class ChineseDate {
*/
public ChineseDate(Date date) {
// 求出和1900年1月31日相差的天数
int offset = (int) ((date.getTime() - BASE_DATE) / DateUnit.DAY.getMillis());
int offset = (int) ((date.getTime() / DateUnit.DAY.getMillis()) - BASE_DAY);
// 计算农历年份
// 用offset减去每农历年的天数计算当天是农历第几天offset是当年的第几天
int daysOfYear;
int iYear = LunarInfo.BASE_YEAR;
final int maxYear = LunarInfo.getMaxYear();
for (; iYear <= maxYear; iYear++) {
for (; iYear <= LunarInfo.MAX_YEAR; iYear++) {
daysOfYear = LunarInfo.yearDays(iYear);
if (offset < daysOfYear) {
break;
@ -299,7 +300,7 @@ public class ChineseDate {
if (D >= firstNode) {
gzM = GanZhi.cyclicalm((Y - LunarInfo.BASE_YEAR) * 12 + M + 12);
}
int dayCyclical = (int) ((DateUtil.parseDate(Y + "-" + M + "-" + "1").getTime() - BASE_DATE + 2592000000L) / DateUnit.DAY.getMillis()) + 10;
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 + "";
}

View File

@ -26,7 +26,7 @@ public class DateBetween implements Serializable{
*
* @param begin 起始时间
* @param end 结束时间
* @return {@link DateBetween}
* @return DateBetween
* @since 3.2.3
*/
public static DateBetween create(Date begin, Date end) {
@ -40,7 +40,7 @@ public class DateBetween implements Serializable{
* @param begin 起始时间
* @param end 结束时间
* @param isAbs 日期间隔是否只保留绝对值正数
* @return {@link DateBetween}
* @return DateBetween
* @since 3.2.3
*/
public static DateBetween create(Date begin, Date end, boolean isAbs) {

View File

@ -1,33 +1,108 @@
package cn.hutool.core.date;
import java.time.temporal.ChronoUnit;
/**
* 日期时间单位每个单位都是以毫秒为基数
* @author Looly
*
* @author Looly
*/
public enum DateUnit {
/** 一毫秒 */
MS(1),
/** 一秒的毫秒数 */
SECOND(1000),
/**一分钟的毫秒数 */
/**
* 一毫秒
*/
MS(1),
/**
* 一秒的毫秒数
*/
SECOND(1000),
/**
* 一分钟的毫秒数
*/
MINUTE(SECOND.getMillis() * 60),
/**一小时的毫秒数 */
/**
* 一小时的毫秒数
*/
HOUR(MINUTE.getMillis() * 60),
/**一天的毫秒数 */
/**
* 一天的毫秒数
*/
DAY(HOUR.getMillis() * 24),
/**一周的毫秒数 */
/**
* 一周的毫秒数
*/
WEEK(DAY.getMillis() * 7);
private final long millis;
DateUnit(long millis){
DateUnit(long millis) {
this.millis = millis;
}
/**
* @return 单位对应的毫秒数
*/
public long getMillis(){
public long getMillis() {
return this.millis;
}
/**
* 单位兼容转换将DateUnit转换为对应的{@link ChronoUnit}
*
* @return {@link ChronoUnit}
* @since 5.4.5
*/
public ChronoUnit toChronoUnit() {
return DateUnit.toChronoUnit(this);
}
/**
* 单位兼容转换{@link ChronoUnit}转换为对应的DateUnit
*
* @param unit {@link ChronoUnit}
* @return DateUnitnull表示不支持此单位
* @since 5.4.5
*/
public static DateUnit of(ChronoUnit unit) {
switch (unit) {
case MICROS:
return DateUnit.MS;
case SECONDS:
return DateUnit.SECOND;
case MINUTES:
return DateUnit.MINUTE;
case HOURS:
return DateUnit.HOUR;
case DAYS:
return DateUnit.DAY;
case WEEKS:
return DateUnit.WEEK;
}
return null;
}
/**
* 单位兼容转换将DateUnit转换为对应的{@link ChronoUnit}
*
* @param unit DateUnit
* @return {@link ChronoUnit}
* @since 5.4.5
*/
public static ChronoUnit toChronoUnit(DateUnit unit) {
switch (unit) {
case MS:
return ChronoUnit.MICROS;
case SECOND:
return ChronoUnit.SECONDS;
case MINUTE:
return ChronoUnit.MINUTES;
case HOUR:
return ChronoUnit.HOURS;
case DAY:
return ChronoUnit.DAYS;
case WEEK:
return ChronoUnit.WEEKS;
}
return null;
}
}

View File

@ -9,11 +9,14 @@ import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalUnit;
import java.util.Date;
@ -412,14 +415,43 @@ public class LocalDateTimeUtil {
* <p>
* 返回结果为{@link Duration}对象通过调用toXXX方法返回相差单位
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param startTimeInclude 开始时间包含
* @param endTimeExclude 结束时间不包含
* @return 时间差 {@link Duration}对象
* @see TemporalUtil#between(Temporal, Temporal)
*/
public static Duration between(LocalDateTime startTime, LocalDateTime endTime) {
return Duration.between(startTime, endTime);
public static Duration between(LocalDateTime startTimeInclude, LocalDateTime endTimeExclude) {
return TemporalUtil.between(startTimeInclude, endTimeExclude);
}
/**
* 获取两个日期的差如果结束时间早于开始时间获取结果为负
* <p>
* 返回结果为时间差的long值
*
* @param startTimeInclude 开始时间包括
* @param endTimeExclude 结束时间不包括
* @param unit 时间差单位
* @return 时间差
* @since 5.4.5
*/
public static long between(LocalDateTime startTimeInclude, LocalDateTime endTimeExclude, ChronoUnit unit) {
return TemporalUtil.between(startTimeInclude, endTimeExclude, unit);
}
/**
* 获取两个日期的表象时间差如果结束时间早于开始时间获取结果为负
* <p>
* 比如2011年2月1日和2021年8月11日日相差了10天月相差6月
*
* @param startTimeInclude 开始时间包括
* @param endTimeExclude 结束时间不包括
* @return 时间差
* @since 5.4.5
*/
public static Period betweenPeriod(LocalDate startTimeInclude, LocalDate endTimeExclude) {
return Period.between(startTimeInclude, endTimeExclude);
}
/**
* 修改为一天的开始时间例如2020-02-02 00:00:00,000

View File

@ -20,7 +20,7 @@ import java.time.temporal.TemporalField;
* @author looly
* @since 5.3.9
*/
public class TemporalAccessorUtil {
public class TemporalAccessorUtil extends TemporalUtil{
/**
* 安全获取时间的某个属性属性不存在返回0

View File

@ -0,0 +1,41 @@
package cn.hutool.core.date;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
/**
* {@link Temporal} 工具类封装
*
* @author looly
* @since 5.4.5
*/
public class TemporalUtil {
/**
* 获取两个日期的差如果结束时间早于开始时间获取结果为负
* <p>
* 返回结果为{@link Duration}对象通过调用toXXX方法返回相差单位
*
* @param startTimeInclude 开始时间包含
* @param endTimeExclude 结束时间不包含
* @return 时间差 {@link Duration}对象
*/
public static Duration between(Temporal startTimeInclude, Temporal endTimeExclude) {
return Duration.between(startTimeInclude, endTimeExclude);
}
/**
* 获取两个日期的差如果结束时间早于开始时间获取结果为负
* <p>
* 返回结果为时间差的long值
*
* @param startTimeInclude 开始时间包括
* @param endTimeExclude 结束时间不包括
* @param unit 时间差单位
* @return 时间差
*/
public static long between(Temporal startTimeInclude, Temporal endTimeExclude, ChronoUnit unit) {
return unit.between(startTimeInclude, endTimeExclude);
}
}

View File

@ -40,13 +40,18 @@ public class LunarInfo {
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252,//2090-2099
};
// 支持的最大年限
public static final int MAX_YEAR = BASE_YEAR + LUNAR_CODE.length - 1;
/**
* 获取支持的最大年包括
*
* @return 最大年包括
* @deprecated 使用 {@link #MAX_YEAR}
*/
@Deprecated
public static int getMaxYear() {
return BASE_YEAR + LUNAR_CODE.length - 1;
return MAX_YEAR;
}
/**

View File

@ -85,4 +85,14 @@ public class ChineseDateTest {
ChineseDate chineseDate = new ChineseDate(DateUtil.parseDate("2023-01-20"));
Assert.assertTrue(StrUtil.isEmpty(chineseDate.getFestivals()));
}
@Test
public void dateTest(){
// 修复这两个日期不正确的问题
// 问题出在计算与1900-01-31相差天数的问题上了相差天数非整天
ChineseDate date = new ChineseDate(DateUtil.parseDate("1991-09-14"));
Assert.assertEquals("辛未羊年 八月初七", date.toString());
date = new ChineseDate(DateUtil.parseDate("1991-09-15"));
Assert.assertEquals("辛未羊年 八月初八", date.toString());
}
}