欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-02-29 20:11:58
...

在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为我们提供了这样的功能,既然知道了就尽量使用吧。

相关标签: Java