Java JDK1.8 time interval calculation class Period and Duration

In Java projects, time formatting is often used. Before JDK1.8, we used our own packaged time tool class to achieve. After 1.8, we can use the Period and Duration provided by it to implement time interval and conversion calculations. Using these two tools, we can calculate year, month, day, week, day, hour, minute, second, nanosecond, etc.

table of Contents

Traditional Package Util Tool

Period time interval calculation

Duration time calculation


Traditional Package Util Tool

This kind of tool is very common in projects:

package com.patrol.beans.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期工具类
 *
 * @author PJL
 */
public class DateUtil {

    /**
     * 格式化日期和时间
     */
    public static SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 格式化日期
     */
    public static SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 获取当前日期yyyy-MM-dd
     *
     * @return
     */
    public static String getDate() {
        return sdfDate.format(new Date());
    }

    /**
     * 获取当前日期
     *
     * @return
     */
    public static String getCurrentDate() {
        Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH) + 1;
        int day = c.get(Calendar.DATE);
        return "" + year + "-" + month + "-" + day;
    }

    /**
     * 获取当前日期和时间
     *
     * @return
     */
    public static String getCurrentDateTime() {
        Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH) + 1;
        int day = c.get(Calendar.DATE);
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);
        int second = c.get(Calendar.SECOND);
        return "" + year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
    }

    /**
     * 获取当前日期前若干天或者后若干天的日期
     *
     * @param dayCount ,天数,正数为之后,负数为之前
     * @return
     */
    public static String getIntervalDay(int dayCount) {
        //SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
        Date beginDate = new Date();
        Calendar date = Calendar.getInstance();
        date.setTime(beginDate);
        date.set(Calendar.DATE, date.get(Calendar.DATE) + dayCount);
        return sdfDate.format(date.getTime());
    }

    /**
     * 获取昨天的日期
     *
     * @return
     */
    public static String getYesterdayDate() {
        return getIntervalDay(-1);
    }

    /**
     * 获取今天的日期
     *
     * @return
     */
    public static String getTodayDate() {
        return getIntervalDay(0);
    }

    /**
     * 获取明天的日期
     *
     * @return
     */
    public static String getTomorrowDate() {
        return getIntervalDay(1);
    }

    /**
     * 获取明天的时间LONG
     *
     * @return
     */
    public static Long getTomorrowTime() {
        String tomorrowDate = DateUtil.getTomorrowDate();
        return DateUtil.getSpecifiedDayTime(tomorrowDate);
    }

    /**
     * 获取日期时间
     *
     * @param dateTime
     * @return
     */
    public static Long getLongTime(String dateTime) {
        Calendar c = Calendar.getInstance();
        Date date = null;
        try {
            date = sdfTime.parse(dateTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date.getTime();
    }

    /**
     * 获得指定日期的前一天
     *
     * @param specifiedDay
     * @return
     * @throws Exception
     */
    public static String getSpecifiedDayBefore(String specifiedDay) {
        // SimpleDateFormat simpleDateFormat = new
        // SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        Date date = null;
        try {
            date = sdfDate.parse(specifiedDay);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.setTime(date);
        int day = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day - 1);

        String dayBefore = sdfDate.format(c.getTime());
        return dayBefore;
    }

    /**
     * 获得指定日期的后一天
     *
     * @param specifiedDay
     * @return
     */
    public static String getSpecifiedDayAfter(String specifiedDay) {
        Calendar c = Calendar.getInstance();
        Date date = null;
        try {
            date = sdfDate.parse(specifiedDay);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.setTime(date);
        int day = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day + 1);

        String dayAfter = sdfDate.format(c.getTime());
        return dayAfter;
    }

    /**
     * 获取指定日期的时间LONG类型
     *
     * @param specifiedDay
     * @return
     */
    public static Long getSpecifiedDayTime(String specifiedDay) {
        Date date = null;
        try {
            date = sdfDate.parse(specifiedDay);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date.getTime();
    }

    /**
     * 获取时差日期和时间
     *
     * @param time 负数向前时间,正数向后时间
     * @return
     */
    public static String getDateTime(Date date, long time) {
        date.setTime(time);
        return sdfTime.format(date);
    }

    /**
     * 增加或减少当前日期的毫秒数
     *
     * @param pastOrFutureTime 负数向前时间,正数向后时间
     * @return
     */
    public static String getAddDateTime(long pastOrFutureTime) {
        Date date = new Date();
        pastOrFutureTime = date.getTime() + pastOrFutureTime;
        date.setTime(pastOrFutureTime);
        return sdfTime.format(date);
    }

    /**
     * 时间毫秒设置日期格式化
     *
     * @param time
     * @return
     */
    public static String setDateTime(long time) {
        Date date = new Date();
        date.setTime(time);
        return sdfTime.format(date);
    }
}

The traditional encapsulation mode is not flexible enough for time calculation and cannot completely cover all business scenarios. You have to modify this tool class when needed. 

Period time interval calculation

There are the following ways to create Period:

  • ZERO sky
  • between
  • of*

Here is an example of Period Junit:

package com.forestar.patrol;

import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Test;
import java.time.LocalDate;
import java.time.Period;

/**
 * @Copyright: 2019-2021
 * @FileName: PeriodTest.javaPJL
 * @Author:
 * @Date: 2020/9/29 8:37
 * @Description: 时间差区间计算
 */
@Slf4j
public class PeriodTest {

    /**
     * 常用方法
     */
    @Test
    public void test(){
        log.info("method ============================test()");
        LocalDate startDate = LocalDate.of(2020, 9, 20);
        LocalDate endDate = LocalDate.of(2020, 12, 29);
        log.info("yyyy-MM-dd = {}",(startDate.getYear()+"-"+startDate.getMonth().getValue()+"-"+startDate.getDayOfMonth()));
        log.info("yyyy-MM-dd = {}",(endDate.getYear()+"-"+endDate.getMonth().getValue()+"-"+endDate.getDayOfMonth()));

        Period periodZero = Period.ZERO;
        Period periodYMD = Period.of(20,3,1);
        Period periodYear = Period.ofYears(1);
        Period periodMonth = Period.ofMonths(2);
        Period periodDay = Period.ofDays(2);
        Period periodWeek = Period.ofWeeks(23);

        Period period = Period.between(startDate, endDate);

        log.info("isZero() = {}",period.isZero());
        log.info("isNegative() = {}",period.isNegative());

        log.info("getYears() = {}",period.getYears());
        log.info("getMonths() = {}",period.getMonths());
        log.info("getDays() = {}",period.getDays());
        log.info("getUnits() = {}",period.getUnits());
        log.info("getChronology() = {}",period.getChronology());

        log.info("withYears(1) = {}",period.withYears(1));// P1Y9D
        log.info("withMonths(1) = {}",period.withMonths(1));//P1M9D
        log.info("withDays(1) = {}",period.withDays(1));//P1D

        log.info("toString() = {}",period.toString());
    }

    /**
     * 创建Period[注意周期不是具体的年月日而是差值]
     */
    @Test
    public void createPeriod(){
        log.info("method ============================createPeriod()");
        Period fromCharYears = Period.parse("P2020Y");
        Assert.assertEquals(2020, fromCharYears.getYears());
        log.info("getYears() = {}",fromCharYears.getYears());

        Period fromCharUnits = Period.parse("P2020Y9M29D");
        Assert.assertEquals(29, fromCharUnits.getDays());
        log.info("getDays() = {}",fromCharUnits.getDays());
    }

    /**
     * 计算加减
     */
    @Test
    public void calculate(){
        log.info("method ============================calculate()");
        Period period = Period.parse("P9M56D");
        int days = period.plusDays(50).getDays();
        log.info("getDays() = {}",days);
        int months = period.minusMonths(2).getMonths();
        log.info("getMonths() = {}",months);
    }
}

Output result:

2020-09-29 09:35:45.026 [main] INFO  com.forestar.patrol.PeriodTest | method ============================calculate()
2020-09-29 09:35:45.084 [main] INFO  com.forestar.patrol.PeriodTest | getDays() = 106
2020-09-29 09:35:45.090 [main] INFO  com.forestar.patrol.PeriodTest | getMonths() = 7
2020-09-29 09:35:45.100 [main] INFO  com.forestar.patrol.PeriodTest | method ============================test()
2020-09-29 09:35:45.108 [main] INFO  com.forestar.patrol.PeriodTest | yyyy-MM-dd = 2020-9-20
2020-09-29 09:35:45.108 [main] INFO  com.forestar.patrol.PeriodTest | yyyy-MM-dd = 2020-12-29
2020-09-29 09:35:45.265 [main] INFO  com.forestar.patrol.PeriodTest | isZero() = false
2020-09-29 09:35:45.265 [main] INFO  com.forestar.patrol.PeriodTest | isNegative() = false
2020-09-29 09:35:45.265 [main] INFO  com.forestar.patrol.PeriodTest | getYears() = 0
2020-09-29 09:35:45.265 [main] INFO  com.forestar.patrol.PeriodTest | getMonths() = 3
2020-09-29 09:35:45.266 [main] INFO  com.forestar.patrol.PeriodTest | getDays() = 9
2020-09-29 09:35:45.266 [main] INFO  com.forestar.patrol.PeriodTest | getUnits() = [Years, Months, Days]
2020-09-29 09:35:45.280 [main] INFO  com.forestar.patrol.PeriodTest | getChronology() = ISO
2020-09-29 09:35:45.280 [main] INFO  com.forestar.patrol.PeriodTest | withYears(1) = P1Y3M9D
2020-09-29 09:35:45.280 [main] INFO  com.forestar.patrol.PeriodTest | withMonths(1) = P1M9D
2020-09-29 09:35:45.280 [main] INFO  com.forestar.patrol.PeriodTest | withDays(1) = P3M1D
2020-09-29 09:35:45.281 [main] INFO  com.forestar.patrol.PeriodTest | toString() = P3M9D
2020-09-29 09:35:45.281 [main] INFO  com.forestar.patrol.PeriodTest | method ============================createPeriod()
2020-09-29 09:35:45.281 [main] INFO  com.forestar.patrol.PeriodTest | getYears() = 2020
2020-09-29 09:35:45.282 [main] INFO  com.forestar.patrol.PeriodTest | getDays() = 29

Duration time calculation

 使用Duration.of*(param)初始化一个Duration实例。

The following is an example of a Duration Junit test:

package com.forestar.patrol;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import java.time.Duration;

/**
 * @Copyright: 2019-2021
 * @FileName: DurationTest.java
 * @Author: PJL
 * @Date: 2020/9/29 9:03
 * @Description: 时间计算
 */
@Slf4j
public class DurationTest {

    @Test
    public void test(){
        //86400是一天的秒计算量
        Duration d = Duration.ofSeconds(86400);
        log.info("getSeconds() = {}",d.getSeconds());
        log.info("getNano() = {}",d.getNano());
        log.info("getUnits() = {}",d.getUnits());
        log.info("isNegative() = {}",d.isNegative());
        log.info("isZero() = {}",d.isZero());
        log.info("toDays() = {}",d.toDays());

        log.info("toHours() = {}",d.toHours());
        log.info("toMinutes() = {}",d.toMinutes());
        log.info("toNanos() = {}",d.toNanos());
        log.info("toMillis() = {}",d.toMillis());
        log.info("toString() = {}",d.toString());
    }
}

Test output result:

2020-09-29 09:52:07.650 [main] INFO  com.forestar.patrol.DurationTest | getSeconds() = 86400
2020-09-29 09:52:07.730 [main] INFO  com.forestar.patrol.DurationTest | getNano() = 0
2020-09-29 09:52:07.732 [main] INFO  com.forestar.patrol.DurationTest | getUnits() = [Seconds, Nanos]
2020-09-29 09:52:07.732 [main] INFO  com.forestar.patrol.DurationTest | isNegative() = false
2020-09-29 09:52:07.732 [main] INFO  com.forestar.patrol.DurationTest | isZero() = false
2020-09-29 09:52:07.733 [main] INFO  com.forestar.patrol.DurationTest | toDays() = 1
2020-09-29 09:52:07.733 [main] INFO  com.forestar.patrol.DurationTest | toHours() = 24
2020-09-29 09:52:07.734 [main] INFO  com.forestar.patrol.DurationTest | toMinutes() = 1440
2020-09-29 09:52:07.734 [main] INFO  com.forestar.patrol.DurationTest | toNanos() = 86400000000000
2020-09-29 09:52:07.735 [main] INFO  com.forestar.patrol.DurationTest | toMillis() = 86400000
2020-09-29 09:52:07.737 [main] INFO  com.forestar.patrol.DurationTest | toString() = PT24H

 The JDK provides us with such a function. Now that you know it, try to use it as much as possible.

Guess you like

Origin blog.csdn.net/boonya/article/details/108862243