Java JDK1.8时间区间计算类Period和Duration

在Java项目中,时间格式化在很多时候都会用到。在JDK1.8之前我们都是通过自己封装的时间工具类来实现,在1.8之后我们可以使用它提供的Period和Duration来实现时间区间和转换计算。使用这两个工具,我们可以计算年、月、日、周、天、时、分、秒、纳秒等。

目录

传统封装Util工具

Period时间区间计算

Duration时间计算


传统封装Util工具

这种工具类在项目中非常普遍:

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);
    }
}

传统封装模式,对时间计算不够灵活,不能完全覆盖所有业务场景,需要的时候还得修改这个工具类。 

Period时间区间计算

创建Period有以下方式:

  • ZERO 空
  • between
  • 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);
    }
}

输出结果:

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时间计算

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

下面是一个Duration Junit测试示例:

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());
    }
}

测试输出结果:

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

 JDK为我们提供了这样的功能,既然知道了就尽量使用吧。

©️2020 CSDN 皮肤主题: 护眼 设计师:闪电赇 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值