实际使用中,经常需要使用不同精确度的Date,比如保留到天 2020-04-23 00:00:00,保留到小时,保留到分钟,保留到秒等,常见的方法是通过格式化到指定精确度(比如:yyyy-MM-dd),然后再解析为Date。Java8中可以用更多的方法来实现这个需求,下面使用三种方法:使用Format方法、 使用Of方法和使用With方法,性能对比,使用Of方法性能最优。
1.减少时间精确度的三种方法和性能比较
这里使用LocalDateTime 保留到(yyyy-MM-dd)天做为实例对比。
1.1 使用Format方法减少精度到天,先格式化,再解析
LocalDateTime ldt = LocalDateTime.now(); LocalDateTime ldt2 = DateTimeFormatterUtil.parseDateStrToLocalDateTime(DateTimeFormatterUtil.formatToDateStr(ldt)); System.out.println("reduceAccuracyFormat result:"+ldt2);
输出:
reduceAccuracyFormat result:2020-04-23T00:00
1.2 使用Of方法减少精度到天
LocalDateTime ldt = LocalDateTime.now(); LocalDateTime ldt2 = LocalDateTime.of(ldt.getYear(), ldt.getMonth().getValue(), ldt.getDayOfMonth(), 0, 0); System.out.println("reduceAccuracyOf result:"+ldt2);
输出:
reduceAccuracyOf result:2020-04-23T00:00
1.3 使用With方法减少精度到天
LocalDateTime ldt = LocalDateTime.now(); LocalDateTime ldt2 = ldt.withHour(0).withMinute(0).withSecond(0).withNano(0); System.out.println("reduceAccuracyOf result:"+ldt2);
输出:
reduceAccuracyWith result:2020-04-23T00:00
1.4 3种方法性能比较
package com.xkzhangsan.time.test; import java.time.LocalDateTime; import org.junit.Test; import com.xkzhangsan.time.formatter.DateTimeFormatterUtil; /** * 日期计算,性能测试类 * @ClassName: CalculatorPerformanceTest * @Description: CalculatorPerformanceTest * @author xkzhangsan * @date 2020年4月22日 */ public class CalculatorPerformanceTest { /** * 使用Format方法减少精度到天 */ @Test public void reduceAccuracyFormat(){ LocalDateTime ldt = LocalDateTime.now(); LocalDateTime ldt2 = null; long s = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) { ldt2 = DateTimeFormatterUtil.parseDateStrToLocalDateTime(DateTimeFormatterUtil.formatToDateStr(ldt)); } System.out.println("reduceAccuracyFormat cost:"+(System.currentTimeMillis()-s)); System.out.println("reduceAccuracyFormat result:"+ldt2); } /** * 使用Of方法减少精度到天 */ @Test public void reduceAccuracyOf(){ LocalDateTime ldt = LocalDateTime.now(); LocalDateTime ldt2 = null; long s = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) { ldt2 = LocalDateTime.of(ldt.getYear(), ldt.getMonth().getValue(), ldt.getDayOfMonth(), 0, 0); } System.out.println("reduceAccuracyOf cost:"+(System.currentTimeMillis()-s)); System.out.println("reduceAccuracyOf result:"+ldt2); } /** * 使用With方法减少精度到天 */ @Test public void reduceAccuracyWith(){ LocalDateTime ldt = LocalDateTime.now(); LocalDateTime ldt2 = null; long s = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) { ldt2 = ldt.withHour(0).withMinute(0).withSecond(0).withNano(0); } System.out.println("reduceAccuracyWith cost:"+(System.currentTimeMillis()-s)); System.out.println("reduceAccuracyWith result:"+ldt2); } }
输出:
reduceAccuracyFormat cost:333 reduceAccuracyFormat result:2020-04-23T00:00 reduceAccuracyOf cost:19 reduceAccuracyOf result:2020-04-23T00:00 reduceAccuracyWith cost:24 reduceAccuracyWith result:2020-04-23T00:00
通过同样运行100000次,对比可以看出,使用Of方法性能最好,使用With方法其次,和Of方法相差不多,但每次调用With会生成一个日期对象,使用Format方法性能最差,和Of方法相差17倍左右。
2 xk-time中的应用
xk-time中使用Of方法减少时间精确度,然后转换为需要的类型如Date。
2.1 代码
/** * 减少时间精度到秒,其他补0,返回如,2020-04-23 15:18:13 * @param localDateTime * @return */ public static LocalDateTime reduceAccuracyToSecond(LocalDateTime localDateTime) { Objects.requireNonNull(localDateTime, "localDateTime"); return LocalDateTime.of(localDateTime.getYear(), localDateTime.getMonthValue(), localDateTime.getDayOfMonth(), localDateTime.getHour(), localDateTime.getMinute(), localDateTime.getSecond()); } /** * 减少时间精度到秒,其他补0,返回如,2020-04-23 15:18:13 * @param date * @return */ public static Date reduceAccuracyToSecond(Date date) { Objects.requireNonNull(date, "date"); return DateTimeConverterUtil.toDate(reduceAccuracyToSecond(DateTimeConverterUtil.toLocalDateTime(date))); } /** * 减少时间精度到分,其他补0,返回如,2020-04-23 15:18:00 * @param localDateTime * @return */ public static LocalDateTime reduceAccuracyToMinute(LocalDateTime localDateTime) { Objects.requireNonNull(localDateTime, "localDateTime"); return LocalDateTime.of(localDateTime.getYear(), localDateTime.getMonthValue(), localDateTime.getDayOfMonth(), localDateTime.getHour(), localDateTime.getMinute(), 0); } /** * 减少时间精度到分,其他补0,返回如,2020-04-23 15:18:00 * @param date * @return */ public static Date reduceAccuracyToMinute(Date date) { Objects.requireNonNull(date, "date"); return DateTimeConverterUtil.toDate(reduceAccuracyToMinute(DateTimeConverterUtil.toLocalDateTime(date))); } /** * 减少时间精度到小时,其他补0,返回如,2020-04-23 15:00:00 * @param localDateTime * @return */ public static LocalDateTime reduceAccuracyToHour(LocalDateTime localDateTime) { Objects.requireNonNull(localDateTime, "localDateTime"); return LocalDateTime.of(localDateTime.getYear(), localDateTime.getMonthValue(), localDateTime.getDayOfMonth(), localDateTime.getHour(), 0, 0); } /** * 减少时间精度到小时,其他补0,返回如,2020-04-23 15:00:00 * @param date * @return */ public static Date reduceAccuracyToHour(Date date) { Objects.requireNonNull(date, "date"); return DateTimeConverterUtil.toDate(reduceAccuracyToHour(DateTimeConverterUtil.toLocalDateTime(date))); } /** * 减少时间精度到天,其他补0,返回如,2020-04-23 00:00:00 * @param localDateTime * @return */ public static LocalDateTime reduceAccuracyToDay(LocalDateTime localDateTime) { Objects.requireNonNull(localDateTime, "localDateTime"); return LocalDateTime.of(localDateTime.getYear(), localDateTime.getMonthValue(), localDateTime.getDayOfMonth(), 0, 0, 0); } /** * 减少时间精度到天,其他补0,返回如,2020-04-23 00:00:00 * @param date * @return */ public static Date reduceAccuracyToDay(Date date) { Objects.requireNonNull(date, "date"); return DateTimeConverterUtil.toDate(reduceAccuracyToDay(DateTimeConverterUtil.toLocalDateTime(date))); }
2.2 测试代码
/** * Date 减少精度测试 */ @Test public void reduceAccuracyDateTest(){ Date date = new Date(); System.out.println(DateTimeFormatterUtil.formatToDateTimeStr(date)); System.out.println(DateTimeFormatterUtil.formatToDateTimeStr(DateTimeCalculatorUtil.reduceAccuracyToSecond(date))); System.out.println(DateTimeFormatterUtil.formatToDateTimeStr(DateTimeCalculatorUtil.reduceAccuracyToMinute(date))); System.out.println(DateTimeFormatterUtil.formatToDateTimeStr(DateTimeCalculatorUtil.reduceAccuracyToHour(date))); System.out.println(DateTimeFormatterUtil.formatToDateTimeStr(DateTimeCalculatorUtil.reduceAccuracyToDay(date))); } /** * LocalDateTime 减少精度测试 */ @Test public void reduceAccuracyLocalDateTimeTest(){ LocalDateTime ldt = LocalDateTime.now(); System.out.println(ldt); System.out.println(DateTimeCalculatorUtil.reduceAccuracyToSecond(ldt)); System.out.println(DateTimeCalculatorUtil.reduceAccuracyToMinute(ldt)); System.out.println(DateTimeCalculatorUtil.reduceAccuracyToHour(ldt)); System.out.println(DateTimeCalculatorUtil.reduceAccuracyToDay(ldt)); }
输出:
2020-04-23 16:04:39 2020-04-23 16:04:39 2020-04-23 16:04:00 2020-04-23 16:00:00 2020-04-23 00:00:00
2020-04-23T16:05:10.233 2020-04-23T16:05:10 2020-04-23T16:05 2020-04-23T16:00 2020-04-23T00:00