Java JDK1.8时间区间计算类Period和Duration
程序员文章站
2024-02-29 20:11:58
...
在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/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为我们提供了这样的功能,既然知道了就尽量使用吧。
上一篇: Spring多对象引入方法
下一篇: Java遗传算法之冲出迷宫
推荐阅读
-
Java JDK1.8时间区间计算类Period和Duration
-
JDK 1.8中Instant时间戳类,Duration类,Period类,等一些与事件相关的类和接口
-
Java8中使用以下类计算日期时间差:Period、Duration、ChronoUnit
-
Java8中使用以下类计算日期时间差:Period、Duration、ChronoUnit
-
Java日期时间API系列9-----Jdk8中java.time包中的新的日期时间API类的Period和Duration的区别
-
Java日期时间API系列9-----Jdk8中java.time包中的新的日期时间API类的Period和Duration的区别
-
Java8中使用以下类计算日期时间差:Period、Duration、ChronoUnit
-
Java8中使用以下类计算日期时间差:Period、Duration、ChronoUnit