Java日期时间API系列30—–Jdk8中java.time包中的新的日期时间API类,减少时间精度方法性能比较和使用。

  实际使用中,经常需要使用不同精确度的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

 

源代码地址:https://github.com/xkzhangsan/xk-time