在Java项目中,时间格式化在很多时候都会用到。在JDK1.8之前我们都是通过自己封装的时间工具类来实现,在1.8之后我们可以使用它提供的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/9https://files.jxasp.com/image/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/9https://files.jxasp.com/image/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为我们提供了这样的功能,既然知道了就尽量使用吧。