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

Period 、Duration常用方法使用与介绍

程序员文章站 2024-01-22 19:48:28
...

java8 的 Period 和Duration 介绍

本文章主要介绍一下 period 以及duration 的主要方法与使用功能

Period 类

可以根据年、月、日来模拟一个数量或者时间量的工具类。使用between()方法可以获取两个日期之间的差作为Period对象返回

	public static void main(String[] args) {
        LocalDate startTime = LocalDate.of(2020,01,30);
        LocalDate endTime = LocalDate.of(2021,04,8);
        Period period = Period.between(startTime,endTime);
        log.info("两个时间之间的差值  年:{},月:{},日:{}",period.getYears(),period.getMonths(),period.getDays());
    }

执行代码可知,我们使用Period.between()方法计算出了两个之间年月日差值,接下来我们在看看Period类还有那些方法

1.of和get

使用of可自定义日期量,使用get方法可获取对应的日期单位量,没有设置的日期默认都为0


    public static void main(String[] args) {
       Period period = Period.of(2021,04,8);
       Period periodYear = Period.ofYears(2021);
       Period periodMonths = Period.ofMonths(04);
       Period periodDays = Period.ofDays(8);
       log.info("给period赋予的值:年:{},月:{},日:{}",period.getYears(),period.getMonths(),period.getDays());
       log.info("给periodYear赋予的值:年:{},月:{},日:{}",periodYear.getYears(),periodYear.getMonths(),periodYear.getDays());
       log.info("给periodMonths赋予的值:年:{},月:{},日:{}",periodMonths.getYears(),periodMonths.getMonths(),periodMonths.getDays());
       log.info("给periodDays赋予的值:年:{},月:{},日:{}",periodDays.getYears(),periodDays.getMonths(),periodDays.getDays());
       log.info("使用get取值{}",period.get(ChronoUnit.YEARS));
    }

执行结果-----
14:16:44.512 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 给period赋予的值:年:2021,月:4,日:8
14:16:44.515 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 给periodYear赋予的值:年:2021,月:0,日:0
14:16:44.515 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 给periodMonths赋予的值:年:0,月:4,日:0
14:16:44.515 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 给periodDays赋予的值:年:0,月:0,日:8
14:16:44.516 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 使用get取值2021

在使用period.get()方法时,我们看到入参使用了ChronoUnit枚举类

2.ChronoUnit 类

用于选择时间的单位

public enum ChronoUnit implements TemporalUnit {
	/**
	* 纳秒概念的单位,最小支持的时间单位。对于ISO日历系统,它等于第二个单位的第1,000,000,000个部分。
	*/
	NANOS("Nanos", Duration.ofNanos(1)),
	/**
	* 微秒概念的单位。对于ISO日历系统,它等于第二个单位的百万分之一。
	*/
	MICROS("Micros", Duration.ofNanos(1000)),
	/**
	* 代表毫秒概念的单位。对于ISO日历系统,它等于第二个单位的千分之一。
	*/
	MILLIS("Millis", Duration.ofNanos(1000_000)),
	/**
	* 代表秒的概念的单位。对于ISO日历系统,除around秒外,它等于SI单位制中的秒。
	*/
	SECONDS("Seconds", Duration.ofSeconds(1)),
	/**
	* 代表分钟概念的单位。对于ISO日历系统,它等于60秒。
	*/
	MINUTES("Minutes", Duration.ofSeconds(60)),
	/**
	* 代表小时概念的单位。对于ISO日历系统,它等于60分钟。
	*/
	HOURS("Hours", Duration.ofSeconds(3600)),
	/*
	* 代表半天概念的单位,用于AM / PM。对于ISO日历系统,它等于12小时。
	*/
	HALF_DAYS("HalfDays", Duration.ofSeconds(43200)),
	/**
	* 代表一天的概念的单位。对于ISO日历系统,这是从午夜到午夜的标准日期。估计一天的持续时间为24小时。
与其他日历系统一起使用时,它必须与地球上太阳升起和落下所定义的日期相对应。不必将日期从午夜开始-在日历系统之间进行转换时,日期应等于午夜。
	*/
	DAYS("Days", Duration.ofSeconds(86400)),
	/**
	* 代表一周概念的单位。对于ISO日历系统,它等于7天。
与其他日历系统一起使用时,它必须对应整数天
	*/
	WEEKS("Weeks", Duration.ofSeconds(7 * 86400L)),
	/**
	* 代表一个月概念的单位。对于ISO日历系统,月份的长度因一年中的月份而异。估计的持续时间为365.2425天的十二分之一。
与其他日历系统一起使用时,它必须对应整数天。
	*/
	MONTHS("Months", Duration.ofSeconds(31556952L / 12)),
	/**
	* 代表一年概念的单位。对于ISO日历系统,它等于12个月。一年的估计持续时间为365.2425天。
当与其他日历系统一起使用时,它必须对应于整数天或月,大约等于地球绕太阳公转所定义的一年。
	*/
	YEARS("Years", Duration.ofSeconds(31556952L)),
	/**
	* 代表十年概念的单位。对于ISO日历系统,它等于10年。
与其他日历系统一起使用时,它必须对应整数天,通常是整数年。
	*/
	DECADES("Decades", Duration.ofSeconds(31556952L * 10L)),
	/**
	* 代表一个世纪概念的单位。对于ISO日历系统,它等于100年。
与其他日历系统一起使用时,它必须对应整数天,通常是整数年。
	*/
	CENTURIES("Centuries", Duration.ofSeconds(31556952L * 100L)),
	/**
	* 代表千年概念的单位。对于ISO日历系统,它等于1000年。
与其他日历系统一起使用时,它必须对应整数天,通常是整数年。
	*/
	MILLENNIA("Millennia", Duration.ofSeconds(31556952L * 1000L)),
	/**
	* 代表时代概念的单位。 ISO日历系统没有纪元,因此无法在日期或日期时间中添加纪元。人为地将时代的估计持续时间定义为1,000,000,000年。
与其他日历系统一起使用时,该装置没有任何限制。
	*/
	ERAS("Eras", Duration.ofSeconds(31556952L * 1000_000_000L)),
	/**
	* 代表永恒概念的人造单位。这主要与TemporalField一起使用,以表示无限制的字段,例如年份或时代。人为地将时代的估计持续时间定义为“持续时间”支持的最大持续时间。
	*/
	FOREVER("Forever", Duration.ofSeconds(Long.MAX_VALUE, 999_999_999));

}

2.isNegative

检查此时间段的三个单位中是否有一个为负数。
这将检查年,月或天的单位是否小于零。
返回值:
如果此期间的任何单位为负,则为true

    public static void main(String[] args) {
       Period period = Period.of(2021,-1,8);
       log.info("校验年月日任何一位值是否有负数:{}",period.isNegative());
    }
    15:12:06.981 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 校验年月日任何一位值是否有负数:true

3.parse

从特定格式的字符串中解析时间,格式为(PnYnMnD or PnW)字符主要要包含四个部分并且按顺序出现,这些部分为年,月,周和日的ASCII后缀“Y”,“M”,“W”,"D"大小写都可以,任何基于周输入的都将乘以7,并是为天数

    public static void main(String[] args) {
       Period period = Period.parse("P2021Y04M8D");
       Period period2 = Period.parse("P2021Y04M1W");
       log.info("period 日期格式:年:{},月:{},日:{}",period.getYears(),period.getMonths(),period.getDays());
       log.info("period2 日期格式:年:{},月:{},日:{}",period2.getYears(),period2.getMonths(),period2.getDays());
    }

10:50:30.194 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - period 日期格式:年:2021,月:4,日:8
10:50:30.197 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - period2 日期格式:年:2021,月:4,日:7

Process finished with exit code 0

plusX()、minuX() 方法进行增加或减少,这里的X只具体的Years、Months、Days

    public static void main(String[] args) {
       Period period = Period.parse("P2021Y04M8D");
       log.info("原来的 period 日期格式:年:{},月:{},日:{}",period.getYears(),period.getMonths(),period.getDays());
       log.info("使用plus后period 日期格式:年:{},月:{},日:{}",period.plusYears(1).getYears(),period.plusMonths(2).getMonths(),period.plusDays(3).getDays());
       log.info("使用minus后period 日期格式:年:{},月:{},日:{}",period.minusYears(1).getYears(),period.minusMonths(2).getMonths(),period.minusDays(3).getDays());
    }

    16:20:44.177 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 原来的 period 日期格式:年:2021,月:4,日:8
16:20:44.180 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 使用plus后period 日期格式:年:2022,月:6,日:11
16:20:44.180 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 使用minus后period 日期格式:年:2020,月:2,日:5

Process finished with exit code 0

Duration 类

duration 此类以秒合纳秒未单位对时间量进行建模,在上个类的基础可更加精密准确的处理时间

between、toDays、toHours、toMinutes、getSeconds、toMillis、toNanos的使用

    public static void main(String[] args) {
        Instant start = Instant.parse("2021-04-13T13:52:30.00Z");
        Instant end = Instant.parse("2021-04-14T10:16:30.00Z");
        Duration duration = Duration.between(start, end);
        log.info("start 和 end 之间的时差值天:{},小时:{},分钟:{},秒:{},毫秒:{},纳秒:{}",
                duration.toDays(),duration.toHours(),duration.toMinutes(),duration.getSeconds(),duration.toMillis(),duration.toNanos());
    }
    
14:11:30.402 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - start 和 end 之间的时差值天:0,小时:20,分钟:1224,秒:73440,毫秒:73440000,纳秒:73440000000000

Process finished with exit code 0

isNegative()

用于校验前面的时间是否大于前面的实际

    public static void main(String[] args) {
        Instant start = Instant.parse("2021-04-13T13:52:30.00Z");
        Instant end = Instant.parse("2021-04-14T10:16:30.00Z");
        Duration duration = Duration.between(end,start);
        log.info("end 是否大于 start :{}",duration.isNegative());
        Duration duration2 = Duration.between(start,end);
        log.info("start 是否大于 end :{}",duration2.isNegative());
    }

14:15:43.360 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - end 是否大于 start :true
14:15:43.364 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - start 是否大于 end :false

Process finished with exit code 0

介绍Duration 的常用方法 如parse()、plus()、minus()等

    public static void main(String[] args) {
        Duration duration = Duration.parse("P1DT5H20M34.42S");
        log.info("转换的时间为  天:{}、小时:{}、分钟:{}、秒:{}、毫秒:{}、纳秒:{}"
                ,duration.toDays(),duration.toHours(),duration.toMinutes(),duration.getSeconds(),duration.toMillis(),duration.toNanos());
        Duration duration2 = duration.parse("P1DT-5H");
        log.info("转换的时间为  天:{}、小时:{}、分钟:{}、秒:{}、毫秒:{}、纳秒:{}"
                ,duration2.toDays(),duration2.toHours(),duration2.toMinutes(),duration2.getSeconds(),duration2.toMillis(),duration2.toNanos());

        /* 单独对天、时、分、秒、毫秒、纳秒 增加或减 */
        log.info("添加指定时间后的结果为   天:{}、小时:{}、分钟:{}、秒:{}、毫秒:{}、纳秒:{}",
                duration2.plus(1,ChronoUnit.DAYS).toDays(),duration2.plus(6,ChronoUnit.HOURS).toHours(),
                duration2.plus(5,ChronoUnit.MINUTES).toMinutes(),duration2.plus(10,ChronoUnit.SECONDS).getSeconds(),
                duration2.plus(10,ChronoUnit.MILLIS).toMillis(),duration2.plus(5,ChronoUnit.NANOS).toNanos());

        log.info("减去指定时间后的结果为   天:{}、小时:{}、分钟:{}、秒:{}、毫秒:{}、纳秒:{}",
                duration2.minusDays(1).toDays(),duration2.minusHours(6).toHours(),
                duration2.minusMinutes(5).toMinutes(),duration2.minusSeconds(10).getSeconds(),
                duration2.minusMillis(10).toMillis(),duration2.minusNanos(5).toNanos());

        /* 使用Duration.ofX()创建指定时间的Duration对象 */
        Duration days = Duration.ofDays(2);
        Duration hours = Duration.ofHours(1);
        Duration minutes = Duration.ofMinutes(50);
        Duration seconds = Duration.ofSeconds(5000);
        Duration millis = Duration.ofMillis(50000);
        Duration nanos = Duration.ofNanos(600000);
        log.info("天:{},小时:{},分钟:{},秒:{},毫秒:{},纳秒:{}",days.toDays(),hours.toHours(),minutes.toMinutes(),seconds.getSeconds(),millis.toMillis(),nanos.toNanos());

        /* 使用Duration.toX()转换时间格式 */
        log.info("分钟:{},秒:{}",hours.toMinutes(),minutes.getSeconds());

    }

15:13:19.748 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 转换的时间为  天:1、小时:29、分钟:1760、秒:105634、毫秒:105634420、纳秒:105634420000000
15:13:19.756 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 转换的时间为  天:0、小时:19、分钟:1140、秒:68400、毫秒:68400000、纳秒:68400000000000
15:13:19.756 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 添加指定时间后的结果为   天:1、小时:25、分钟:1145、秒:68410、毫秒:68400010、纳秒:68400000000005
15:13:19.756 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 减去指定时间后的结果为   天:0、小时:13、分钟:1135、秒:68390、毫秒:68399990、纳秒:68399999999995
15:13:19.756 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 天:2,小时:1,分钟:50,秒:5000,毫秒:50000,纳秒:600000
15:13:19.757 [main] INFO com.gafc.lk.advice.GlobalExceptionHandler - 分钟:60,秒:3000

Process finished with exit code 0

总结

本文我们介绍了Java8 中 Period 和Duration类,并通过实例介绍了其常用方法
本文借鉴了 https://blog.csdn.net/neweastsun/article/details/88770592 博客,在此特别感谢