不灭的焱

革命尚未成功,同志仍须努力下载JDK17

作者:Albert.Wen  添加时间:2023-04-08 23:32:22  修改时间:2024-04-17 07:06:33  分类:Java基础  编辑
  1. Java8新特性:LocalDate、LocalTime、LocalDateTime 使用场景+案例+常用工具类
  2. 【LocalDate】获取两个日期间相差的年数、月数、天数:startDate.until(endDate, ChronoUnit.DAYS))
  3. 【基础】使用 Duration、Period类,计算两个“时间/日期”间隔
  4. 【Hutool】LocalDateTime工具-LocalDateTimeUtil

目录

一.背景

本文主要介绍Java 8中时间的操作方法

  • java.util.Date是用于表示一个日期和时间的对象(注意与java.sql.Date区分,后者用在数据库中没有格式化的Date),它打印出的日期可读性差,可以使用SimpleDateFormat对时间进行格式化,但SimpleDateFormat又是线程不安全,包括format和parse方法,而在时间的计算方面不是很方便。
  • java.util.Canlendar 可以用于获取并设置年、月、日、时、分、秒,它和Date比,主要多了一个可以做简单的日期和时间运算的功能,Canlendar 变量是全局变量,会导致脏变量情况产生,并且这个共享变量没有做线程安全控制,也就是多线程的情况下是线程不安全的。
  • Java8出的新的时间日期API都是线程安全的比如LocalDate、LocalTime、LocalDateTime这三个类,计算功能强大,并且性能更好,代码更简洁。

二.简介

  • LocalDate :表示当前日期,相当于:yyyy-MM-dd
  • LocalTime :表示当前时间,相当于:HH:mm:ss (24小时制) 或者 hh:mm:ss(12小时制)
  • LocalDateTime :表示当前日期时间,相当于:yyyy-MM-ddTHH:mm:ss,是前两者的结合
  • DateTimeFormatter :表示格式化类型,可以取代SimpleDateFormat
  • Instant :表示时刻,用来表示时间线上的一个点(瞬时),也可以说是时间戳
  • ZoneId、ZoneOffset :表示时区
  • ZonedDateTime :表示带时区的日期和时间,是前两者的结合
  • Duration :表示两个时刻之间的时间间隔
  • Period :表示两个日期之间的天数

三.实战

3.1 LocalDate的创建与使用

3.1.1、LocalDate的创建

/**
 * LocalDate的初始化方法
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void init(){
	//1.创建LocalDate,LocalDate对象直接调用now(),获取到当前日期
	LocalDate localDateNow = LocalDate.now();
	System.out.println("1.直接调用now()创建:" + localDateNow);
	//2.直接根据(年月日)创建,如:2021-05-20
	LocalDate localDateOf = LocalDate.of(2021, 5, 20);
	System.out.println("2.根据年月日创建:" + localDateOf);
	//3.直接根据某一年的某一天创建,如 2021年中第200天
	LocalDate localDateOfYearDay = LocalDate.ofYearDay(2021, 200);
	System.out.println("3.根据某一年的某一天创建:" + localDateOfYearDay);
	//4.根据java.time.temporal.TemporalAccessor创建(包括LocalDate,LocalDateTime等等)
	LocalDate localDateFrom = LocalDate.from(LocalDate.now());
	System.out.println("4.根据TemporalAccessor创建:" + localDateFrom);
	//5.根据时间字符串转化创建,调用parse(CharSequence text)方法,此方法只支持yyyy-MM-dd格式的值
	LocalDate localDateParse = LocalDate.parse("2021-05-11");
	System.out.println("5.根据时间字符串转化创建:" + localDateParse);
	//6.根据时间字符串转化创建,调用parse(CharSequence text, DateTimeFormatter formatter)方法,此时的text可以根据formatter多变
	DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
	LocalDate localDateParse2 = LocalDate.parse("20210515", formatter);
	System.out.println("6.根据时间字符串转化创建:" + localDateParse2);
}

运行结果:

1.直接调用now()创建:2021-05-24
2.根据年月日创建:2021-05-20
3.根据某一年的某一天创建:2021-07-19
4.根据TemporalAccessor创建:2021-05-24
5.根据时间字符串转化创建:2021-05-11
6.根据时间字符串转化创建:2021-05-15

3.1.2、LocalDate的常见使用方法

   /**
     * LocalDate的常用使用方法
     * 此处单元测试的注解是采用:org.junit.Test
     */
    @Test
    public void usage() {
        //此处采用LocalDate对象直接调用now(),获取到当前日期,注意:如果使用我的实例,结果会不一样,因为LocalDate.now()是调用时的日期
        LocalDate currentDate = LocalDate.now();
        //1.获取年、月、日、星期几、月中天、年中天、月数
        System.out.println("------------------1.获取年、月、日、星期几、月中天、年中天、月数-----------------------");
        System.out.println("1.获取到的当前日期:" + currentDate);
        System.out.println("1.获取到的年:" + currentDate.getYear());
        System.out.println("1.获取到的月:" + currentDate.getMonthValue());
        System.out.println("1.获取到的一月中的哪一天:" + currentDate.getDayOfMonth());
        System.out.println("1.获取到的一周中的星期几:" + currentDate.getDayOfWeek().getValue());
        System.out.println("1.获取到的一年的第多少天:" + currentDate.getDayOfYear());
        System.out.println("1.获取到的一年有多少天:" + currentDate.lengthOfYear());
        System.out.println("1.获取到的一年有多少月:" + currentDate.lengthOfMonth());
        //2.时间的计算
        System.out.println("-----------------2.时间的计算,主要是加减法------------------------");
        System.out.println("2.获取到的当前日期:" + currentDate);
        System.out.println("2.加法,当前日期上加2年:" + currentDate.plusYears(2));
        System.out.println("2.加法,当前日期上加3个月:" + currentDate.plusMonths(3));
        System.out.println("2.加法,当前日期上加20天:" + currentDate.plusDays(20));
        System.out.println("2.加法,当前日期上加一周:" + currentDate.plusWeeks(1));
        System.out.println("2.减法,当前日期上减2年:" + currentDate.minusYears(2));
        System.out.println("2.减法,当前日期上减3个月:" + currentDate.minusMonths(3));
        System.out.println("2.减法,当前日期上减20天:" + currentDate.minusDays(20));
        System.out.println("2.减法,当前日期上减一周:" + currentDate.minusWeeks(1));
        //3.时间的判断及转化
        System.out.println("-----------------3.时间的判断及格式化(格式化的类型很多)------------------------");
        //新建一个格式化类型
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        //新创建一个LocalDate日期进行比较
        LocalDate localDateOf = LocalDate.of(2020, 5, 20);
        System.out.println("3.当前日期转成yyyyMMdd型的字符串:" + currentDate.format(formatter));
        System.out.println("3.当前日期是否在一个日期之后:" + currentDate.isAfter(localDateOf));
        System.out.println("3.当前日期是否在一个日期之前:" + currentDate.isBefore(localDateOf));
        System.out.println("3.当前日期是否是闰年:" + currentDate.isLeapYear());
        System.out.println("3.2020-05-20是否是闰年:" + localDateOf.isLeapYear());
        //4.根据指定数据获取日期或者时间(LocalTime)
        System.out.println("-----------------4.根据指定数据获取日期或者时间(LocalTime)------------------------");
        System.out.println("4.获取到的当前日期:" + currentDate);
        System.out.println("4.修改年数为1999年:" + currentDate.withYear(1999));
        System.out.println("4.修改月数为10月:" + currentDate.withMonth(10));
        System.out.println("4.修改天数为当月12日:" + currentDate.withDayOfMonth(12));
        System.out.println("4.获取到的当前日期的开始时间:" + currentDate.atStartOfDay());
        System.out.println("4.根据指定的时、分、秒获取时间:" + currentDate.atTime(12, 23, 45));
        System.out.println("4.根据时间LocalTime对象获取时间:" + currentDate.atTime(LocalTime.now()));
    }

运行结果:

------------------1.获取年、月、日、星期几、月中天、年中天、月数-----------------------
1.获取到的当前日期:2021-05-24
1.获取到的年:2021
1.获取到的月:5
1.获取到的一月中的哪一天:24
1.获取到的一周中的星期几:1
1.获取到的一年的第多少天:144
1.获取到的一年有多少天:365
1.获取到的一年有多少月:31
-----------------2.时间的计算,主要是加减法------------------------
2.获取到的当前日期:2021-05-24
2.加法,当前日期上加2年:2023-05-24
2.加法,当前日期上加3个月:2021-08-24
2.加法,当前日期上加20天:2021-06-13
2.加法,当前日期上加一周:2021-05-31
2.减法,当前日期上减2年:2019-05-24
2.减法,当前日期上减3个月:2021-02-24
2.减法,当前日期上减20天:2021-05-04
2.减法,当前日期上减一周:2021-05-17
-----------------3.时间的判断及格式化(格式化的类型很多)------------------------
3.当前日期转成yyyyMMdd型的字符串:20210524
3.当前日期是否在一个日期之后:true
3.当前日期是否在一个日期之前:false
3.当前日期是否是闰年:false
3.2020-05-20是否是闰年:true
-----------------4.根据指定数据获取日期或者时间(LocalTime)------------------------
4.获取到的当前日期:2021-05-24
4.修改年数为1999年:1999-05-24
4.修改月数为10月:2021-10-24
4.修改天数为当月12日:2021-05-12
4.获取到的当前日期的开始时间:2021-05-24T00:00
4.根据指定的时、分、秒获取时间:2021-05-24T12:23:45
4.根据时间LocalTime对象获取时间:2021-05-24T19:49:04.468

3.2 LocalTime的创建与使用

3.2.1、LocalTime创建

/**
 * LocalTime的初始化方法
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void init() {
	//1.LocalTime,LocalTime对象直接调用now(),获取到当前时间
	LocalTime now = LocalTime.now();
	System.out.println("1.获取到的当前时间:" + now);
	//2.根据指定的时分秒生成时间
	LocalTime localTimeOf = LocalTime.of(23, 59, 59);
	System.out.println("2.根据指定的时分秒生成时间:" + localTimeOf);
	//3.根据指定的时分秒生成时间
	LocalTime localTimeParse = LocalTime.parse("12:23:45");
	System.out.println("3.根据指定的时分秒生成时间:" + localTimeParse);
	//4.根据指定的时分秒和格式化类型生成时间
	DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HHmmss");//注意:HH是24小时制,hh是12小时制,时间类型的不要出现年月日如:yyyyMMdd
	LocalTime localTimeParseWithFormatter = LocalTime.parse("102008", formatter);
	System.out.println("4.根据指定的时分秒和格式化类型生成时间:" + localTimeParseWithFormatter);
	//5.根据时间对象TemporalAccessor生成
	LocalTime initTime = LocalTime.of(11, 59, 59);
	System.out.println("5.根据时间对象TemporalAccessor生成:" + LocalTime.from(initTime));
}

运行结果:

1.获取到的当前时间:11:36:05.740
2.根据指定的时分秒生成时间:23:59:59
3.根据指定的时分秒生成时间:12:23:45
4.根据指定的时分秒和格式化类型生成时间:10:20:08
5.根据时间对象TemporalAccessor生成:11:59:59

3.2.2、LocalTime的常见使用方法

/**
 * LocalTime的常用使用方法
 * 此处单元测试的注解是采用:org.junit.Test
 * 和LocalDate的操作方法差不多
 */
@Test
public void usage() {
	//此处采用LocalTime对象直接调用now(),获取到当前时间,注意:如果使用我的实例,结果会不一样,因为LocalTime.now()是调用时的时间
	LocalTime currentTime = LocalTime.now();
	//1.获取时、分、秒
	System.out.println("------------------1.获取时、分、秒-----------------------");
	System.out.println("1.获取到的当前时间:" + currentTime);
	System.out.println("1.获取当前时间的小时:" + currentTime.getHour());
	System.out.println("1.获取当前时间的分钟:" + currentTime.getMinute());
	System.out.println("1.获取当前时间的秒:" + currentTime.getSecond());
	System.out.println("1.获取当前时间的秒:" + currentTime.getNano());
	//2.时间的加减
	System.out.println("------------------2.时间的加减-----------------------");
	System.out.println("2.获取到的当前时间:" + currentTime);
	System.out.println("2.加法:当前时间上增加1小时" + currentTime.plusHours(1));
	System.out.println("2.加法:当前时间上增加10分钟" + currentTime.plusMinutes(10));
	System.out.println("2.加法:当前时间上增加20秒" + currentTime.plusSeconds(20));
	System.out.println("2.减法:当前时间上减加2小时" + currentTime.minusHours(2));
	System.out.println("2.减法:当前时间上减加30分钟" + currentTime.minusMinutes(30));
	System.out.println("2.减法:当前时间上减加5秒" + currentTime.minusSeconds(5));
	System.out.println("------------------3.时间的判断及转化-----------------------");
	//初始化一个新的时间
	LocalTime initTime = LocalTime.of(13, 59, 59);
	System.out.println("3.获取到的当前时间:" + currentTime);
	System.out.println("3.新初始化的时间:" + initTime);
	System.out.println("3.判断当前时间是否是一个时间之后:" + currentTime.isAfter(initTime));
	System.out.println("3.判断当前时间是否是一个时间之前:" + currentTime.isBefore(initTime));
	System.out.println("3.修改小时数为12:" + currentTime.withHour(12));
	System.out.println("3.修改分钟数为12:" + currentTime.withMinute(12));
	System.out.println("3.修改秒数为12:" + currentTime.withSecond(12));
	DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
	LocalTime parseTime = LocalTime.parse("11:45:28", formatter);
	System.out.println("3.根据指定的时分秒和格式化类型生成时间:" + parseTime);
}

运行结果:

------------------1.获取时、分、秒-----------------------
1.获取到的当前时间:19:50:14.612
1.获取当前时间的小时:19
1.获取当前时间的分钟:50
1.获取当前时间的秒:14
1.获取当前时间的秒:612000000
------------------2.时间的加减-----------------------
2.获取到的当前时间:19:50:14.612
2.加法:当前时间上增加1小时20:50:14.612
2.加法:当前时间上增加10分钟20:00:14.612
2.加法:当前时间上增加20秒19:50:34.612
2.减法:当前时间上减加2小时17:50:14.612
2.减法:当前时间上减加30分钟19:20:14.612
2.减法:当前时间上减加5秒19:50:09.612
------------------3.时间的判断及转化-----------------------
3.获取到的当前时间:19:50:14.612
3.新初始化的时间:13:59:59
3.判断当前时间是否是一个时间之后:true
3.判断当前时间是否是一个时间之前:false
3.修改小时数为12:12:50:14.612
3.修改分钟数为12:19:12:14.612
3.修改秒数为12:19:50:12.612
3.根据指定的时分秒和格式化类型生成时间:11:45:28

3.3 LocalDateTime的创建与使用

3.3.1、LocalDateTime创建

/**
 * LocalDateTime的初始化方法
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void init() {
	//1.LocalDateTime对象直接调用now(),获取到当前时间
	LocalDateTime localDateTime = LocalDateTime.now();
	System.out.println("1.LocalDateTime对象直接调用now()获取到的时间:" + localDateTime);
	//2.根据年月日时分秒构造(此处方法比较多,不一一介绍)
	LocalDateTime localDateTimeOf = LocalDateTime.of(2021, 5, 10, 18, 30, 26);
	System.out.println("2.根据年月日时分秒构造获取到的时间:" + localDateTimeOf);
	//3.根据LocalDate和LocalTime得到(在有日期和时间的情况下可以使用)
	LocalDateTime of = LocalDateTime.of(LocalDate.now(), LocalTime.now());
	System.out.println("3.根据LocalDate和LocalTime得到:" + of);
	//4.LocalDate指定一个LocalTime(LocalDate只有年月日)
	LocalTime localTimeInit = LocalTime.of(14, 25, 25);
	LocalDateTime localDateWithLocalTime = LocalDate.now().atTime(localTimeInit);
	System.out.println("4.LocalDate指定一个LocalTime:" + localDateWithLocalTime);
	//5.LocalTime指定一个LocalDate(LocalTime只有时分秒)
	LocalDate localDateInit = LocalDate.of(1998, 10, 1);
	LocalDateTime localTimeWithLocalDate = LocalTime.now().atDate(localDateInit);
	System.out.println("5.LocalTime指定一个LocalDate:" + localTimeWithLocalDate);
}

运行结果:

1.LocalDateTime对象直接调用now()获取到的时间:2021-05-24T19:51:15.237
2.根据年月日时分秒构造获取到的时间:2021-05-10T18:30:26
3.根据LocalDate和LocalTime得到:2021-05-24T19:51:15.238
4.LocalDate指定一个LocalTime:2021-05-24T14:25:25
5.LocalTime指定一个LocalDate:1998-10-01T19:51:15.238

3.3.2、LocalDateTime的常见使用方法

/**
 * LocalDateTime的常用使用方法
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void usage() {
	//1.根据LocalDateTime获取LocalDate
	LocalDateTime currentTime = LocalDateTime.now();
	System.out.println("1.根据LocalDateTime获取LocalDate: " + currentTime.toLocalDate());
	//2.根据LocalDateTime获取LocalTime
	System.out.println("2.根据LocalDateTime获取LocalTime: " + currentTime.toLocalTime());
	System.out.println("------------------3.时间的加减法及修改-----------------------");
	//3.LocalDateTime的加减法包含了LocalDate和LocalTime的所有加减,上面说过,这里就只做简单介绍
	System.out.println("3.当前时间:" + currentTime);
	System.out.println("3.当前时间加5年:" + currentTime.plusYears(5));
	System.out.println("3.当前时间加2个月:" + currentTime.plusMonths(2));
	System.out.println("3.当前时间减2天:" + currentTime.minusDays(2));
	System.out.println("3.当前时间减5个小时:" + currentTime.minusHours(5));
	System.out.println("3.当前时间加5分钟:" + currentTime.plusMinutes(5));
	System.out.println("3.当前时间加20秒:" + currentTime.plusSeconds(20));
	//还可以灵活运用比如:向后加一年,向前减一天,向后加2个小时,向前减5分钟,可以进行连写
	System.out.println("3.同时修改(向后加一年,向前减一天,向后加2个小时,向前减5分钟):" + currentTime.plusYears(1).minusDays(1).plusHours(2).minusMinutes(5));
	System.out.println("3.修改年为2025年:" + currentTime.withYear(2025));
	System.out.println("3.修改月为12月:" + currentTime.withMonth(12));
	System.out.println("3.修改日为27日:" + currentTime.withDayOfMonth(27));
	System.out.println("3.修改小时为12:" + currentTime.withHour(12));
	System.out.println("3.修改分钟为12:" + currentTime.withMinute(12));
	System.out.println("3.修改秒为12:" + currentTime.withSecond(12));
	System.out.println("------------------4.时间的转化及其他-----------------------");
	//4.时间的格式化及其他
	DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	LocalDateTime parse = LocalDateTime.parse("2020-09-18 14:55:44", formatter);
	System.out.println("4.时间字符串转为时间:" + parse);
	LocalDate localDate = LocalDate.now();
	System.out.println("4.所属年份的第一天:" + localDate.with(TemporalAdjusters.firstDayOfYear()));
	System.out.println("4.所属年份的最后一天:" + localDate.with(TemporalAdjusters.lastDayOfYear()));
	System.out.println("4.所属年份的下一年的第一天:" + localDate.with(TemporalAdjusters.firstDayOfNextYear()));
	System.out.println("4.所属月份的第一天:" + localDate.with(TemporalAdjusters.firstDayOfMonth()));
	System.out.println("4.所属月份的最后一天:" + localDate.with(TemporalAdjusters.lastDayOfMonth()));
	System.out.println("4.所属月份的下个月的第一天:" + localDate.with(TemporalAdjusters.firstDayOfNextMonth()));
}

运行结果:

1.根据LocalDateTime获取LocalDate: 2021-05-24
2.根据LocalDateTime获取LocalTime: 19:57:46.316
------------------3.时间的加减法及修改-----------------------
3.当前时间:2021-05-24T19:57:46.316
3.当前时间加5年:2026-05-24T19:57:46.316
3.当前时间加2个月:2021-07-24T19:57:46.316
3.当前时间减2天:2021-05-22T19:57:46.316
3.当前时间减5个小时:2021-05-24T14:57:46.316
3.当前时间加5分钟:2021-05-24T20:02:46.316
3.当前时间加20秒:2021-05-24T19:58:06.316
3.同时修改(向后加一年,向前减一天,向后加2个小时,向前减5分钟):2022-05-23T21:52:46.316
3.修改年为2025年:2025-05-24T19:57:46.316
3.修改月为12月:2021-12-24T19:57:46.316
3.修改日为27日:2021-05-27T19:57:46.316
3.修改小时为12:2021-05-24T12:57:46.316
3.修改分钟为12:2021-05-24T19:12:46.316
3.修改秒为12:2021-05-24T19:57:12.316
------------------4.时间的转化及其他-----------------------
4.时间字符串转为时间:2020-09-18T14:55:44
4.所属年份的第一天:2021-01-01
4.所属年份的最后一天:2021-12-31
4.所属年份的下一年的第一天:2022-01-01
4.所属月份的第一天:2021-05-01
4.所属月份的最后一天:2021-05-31
4.所属月份的下个月的第一天:2021-06-01

3.4 Duration的创建与使用

可能大家总是分不清结果值比如“P2DT3H10M”,“PT11H20M20S”,其实Duration和Period的表示方法也符合ISO 8601的格式,它以P…T…的形式表示,P…T之间表示日期间隔,T后面表示时间间隔。如果是PT…的格式表示仅有时间间隔。

你可以参照一下LocalDateTime的时间格式“yyyy-MM-ddTHH:mm:ss”,其实你看到这个T就知道是什么意思了,用大写的YMD表示年月日,大写的HMS表示时分秒,比如你要写:1年2月3天4时5分6秒 对应的表达式是 “P1Y2M3DT4H5M6S”。

3.4.1、Duration创建

/**
 * duration创建
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void durationInit() {
	//1.Duration的创建:ofXxx()
	Duration durationOf = Duration.ofHours(1); // 1 hours
	System.out.println("1.创建一个1小时间隔的duration:" + durationOf);
	System.out.println("1.1小时间隔的duration对应的秒数:" + durationOf.getSeconds());
	//2.Duration的创建:parse
	Duration durationParse = Duration.parse("P2DT3H10M"); // 2 day, 3 hours, 10 minutes
	System.out.println("2.通过duration的值转化:" + durationParse);// 51小时 10分钟,正好是上面的值的和
	System.out.println("2.转化后对应的秒数:" + durationParse.getSeconds());//获取的秒数
}

运行结果:

1.创建一个1小时间隔的duration:PT1H
1.1小时间隔的duration对应的秒数:3600
2.通过duration的值转化:PT51H10M
2.转化后对应的秒数:184200

3.4.2、Duration的常见使用方法

/**
 * duration简单使用(表示的是两个时间的间隔)
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void durationUsage() {
	LocalDateTime start = LocalDateTime.of(2021, 5, 20, 8, 15, 10);
	LocalDateTime end = LocalDateTime.of(2021, 5, 20, 19, 35, 30);
	//Duration的格式为:P...T...的形式表示,P...T之间表示日期间隔,T后面表示时间间隔。如果是PT...的格式表示仅有时间间隔。不太请求就直接获取秒数间隔
	Duration durationBetween = Duration.between(start, end);
	System.out.println("两个日期之间的间隔为:" + durationBetween); // PT11H20M20S  (11小时20分钟20秒数)
	System.out.println("两个日期时间的间隔秒数为:" + durationBetween.getSeconds());//获取的秒数
}

运行结果:

两个日期之间的间隔为:PT11H20M20S
两个日期时间的间隔秒数为:40820

3.5 Period的创建与使用

3.5.1、Period创建

/**
 * period创建
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void periodInit() {
	//Period.of()创建
	Period periodOf = Period.of(2021, 5, 1);
	System.out.println("1.间隔日期:" + periodOf);
	//Period.ofDays()等创建
	Period periodOfDay = Period.ofDays(20);
	System.out.println("2.间隔日期:" + periodOfDay);
	//通过Period.parse()创建
	Period periodParse = Period.parse("P2Y1M5D"); //2年,1月,5天
	System.out.println("3.间隔日期:" + periodParse);
	System.out.println("3.间隔日期年数:" + periodParse.getYears());
	System.out.println("3.间隔日期月数:" + periodParse.getMonths());
	System.out.println("3.间隔日期天数:" + periodParse.getDays());
}

运行结果:

1.间隔日期:P2021Y5M1D
2.间隔日期:P20D
3.间隔日期:P2Y1M5D
3.间隔日期年数:2
3.间隔日期月数:1
3.间隔日期天数:5

3.5.2、Period的常见使用方法

/**
 * duration简单使用(表示的是两个日期的天数)
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void periodUsage() {
	//两个日期(LocalDate)的间隔
	LocalDate localDateStart = LocalDate.of(2020, 4, 19);
	LocalDate localDateEnd = LocalDate.of(2021, 5, 30);
	Period p = localDateStart.until(localDateEnd);
	System.out.println("两个日期的间隔:" + p); // P1Y1M11D 即:1年1月11天
	//可以获取Period对应的年,月,日,也可以进行加减
	System.out.println("两个日期的间隔年:" + p.getYears());
	System.out.println("两个日期的间隔月:" + p.getMonths());
	System.out.println("两个日期的间隔天:" + p.getDays());
	System.out.println("Period加2个月:" + p.plusMonths(2));
	System.out.println("Period减4天:" + p.minusDays(4));
}

运行结果:

两个日期的间隔:P1Y1M11D
两个日期的间隔年:1
两个日期的间隔月:1
两个日期的间隔天:11
Period加2个月:P1Y3M11D
Period减4天:P1Y1M7D

3.5.3、计算两个日期之间的天数和月数

Java 8中可以用java.time.Period类用来计算两个日期之间的天数、周数或月数。

LocalDate today = LocalDate.now();
LocalDate java8time = LocalDate.of(2019, Month.AUGUST, 31);
Period period = Period.between(java8time, today);
System.out.printf("从2019年8月31到现在过去了 %d 个月。\n", period.getMonths());

卧槽,什么情况,从2019年8月31到现在(2021-09-30)过去了 0 个月。

我们debug看一下:原来period参数中的组成是年、月、日

我们将获取到的相差的年数 * 12 再加上月数就好了撒。

int periodMonth = period.getYears() * 12 + period.getMonths();
System.out.printf("修正版:从2019年8月31到现在过去了 %d 个月。\n", periodMonth);

3.6 LocalDateTime、LocalDate、Date、timestamp、时间字符串之间的转化

3.6.1、Date转LocalDateTime

/**
 * date转LocalDateTime
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void dateToLocalDateTime() {
	System.out.println("------------------方法一:分步写-----------------------");
	//实例化一个时间对象
	Date date = new Date();
	//返回表示时间轴上同一点的瞬间作为日期对象
	Instant instant = date.toInstant();
	//获取系统默认时区
	ZoneId zoneId = ZoneId.systemDefault();
	//根据时区获取带时区的日期和时间
	ZonedDateTime zonedDateTime = instant.atZone(zoneId);
	//转化为LocalDateTime
	LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
	System.out.println("方法一:原Date = " + date);
	System.out.println("方法一:转化后的LocalDateTime = " + localDateTime);

	System.out.println("------------------方法二:一步到位(推荐使用)-----------------------");
	//实例化一个时间对象
	Date todayDate = new Date();
	//Instant.ofEpochMilli(long l)使用1970-01-01T00:00:00Z的纪元中的毫秒来获取Instant的实例
	LocalDateTime ldt = Instant.ofEpochMilli(todayDate.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
	System.out.println("方法二:原Date = " + todayDate);
	System.out.println("方法二:转化后的LocalDateTime = " + ldt);
}

运行结果:

------------------方法一:分步写-----------------------
方法一:原Date = Mon May 24 20:29:06 CST 2021
方法一:转化后的LocalDateTime = 2021-05-24T20:29:06.158
------------------方法二:一步到位-----------------------
方法二:原Date = Mon May 24 20:29:06 CST 2021
方法二:转化后的LocalDateTime = 2021-05-24T20:29:06.197

3.6.2、LocalDateTime转Date

/**
 * LocalDateTime转date
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void localDateTimeToDate() {
	System.out.println("------------------方法一:分步写-----------------------");
	//获取LocalDateTime对象,当前时间
	LocalDateTime localDateTime = LocalDateTime.now();
	//获取系统默认时区
	ZoneId zoneId = ZoneId.systemDefault();
	//根据时区获取带时区的日期和时间
	ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
	//返回表示时间轴上同一点的瞬间作为日期对象
	Instant instant = zonedDateTime.toInstant();
	//转化为Date
	Date date = Date.from(instant);
	System.out.println("方法一:原LocalDateTime = " + localDateTime);
	System.out.println("方法一:转化后的Date = " + date);

	System.out.println("------------------方法二:一步到位(推荐使用)-----------------------");
	//实例化一个LocalDateTime对象
	LocalDateTime now = LocalDateTime.now();
	//转化为date
	Date dateResult = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
	System.out.println("方法二:原LocalDateTime = " + now);
	System.out.println("方法二:转化后的Date = " + dateResult);
}

运行结果:

------------------方法一:分步写-----------------------
方法一:原LocalDateTime = 2021-05-24T20:31:28.661
方法一:转化后的Date = Mon May 24 20:31:28 CST 2021
------------------方法二:一步到位-----------------------
方法二:原LocalDateTime = 2021-05-24T20:31:28.664
方法二:转化后的Date = Mon May 24 20:31:28 CST 2021

3.6.3、LocalDateTime转时间字符串

/**
 * LocalDateTime转字符串
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void localDateTimeFormatter() {
	//实例化对象
	LocalDateTime localDateTime = LocalDateTime.now();
	System.out.println("当前时间:" + localDateTime);
	//这里的格式就很多了,可以自由发挥
	DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
	System.out.println("把当前时间格式化时间字符串:" + dtf.format(localDateTime));
}

运行结果:

当前时间:2021-05-24T20:50:22.393
把当前时间格式化时间字符串:20210524205022

3.6.4、时间字符串转LocalDateTime

/**
 * 时间字符串转LocalDateTime
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void timeStrToLocalDateTime() {
	String timeStr = "20210524204125";
	System.out.println("时间字符串为:" + timeStr);
	//这里的格式就很多了,可以自由发挥
	DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
	System.out.println("时间字符串转为LocalDateTime: " + LocalDateTime.parse(timeStr, dtf));
}

运行结果:

时间字符串为:20210524204125
时间字符串转为LocalDateTime: 2021-05-24T20:41:25

3.6.5、LocalDateTime转long类型的timestamp

/**
 * LocalDateTime转long类型的timestamp
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void localDateTimeToTimestamp(){
	//获取当前时间(也可以是其他LocalDateTime类型的时间),具体的说明上面事例有说明
	LocalDateTime localDateTime = LocalDateTime.now();
	ZoneId zoneId = ZoneId.systemDefault();
	ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
	Instant instant = zonedDateTime.toInstant();
	long l = instant.toEpochMilli();
	System.out.println("LocalDateTime转long类型的timestamp(分步计算): "+l);
	//一步到位的写法(推荐使用)
	long timestampLongValue =localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
	System.out.println("LocalDateTime转long类型的timestamp(一步到位): "+timestampLongValue);
}

运行结果:

LocalDateTime转long类型的timestamp(分步计算): 1621908333726
LocalDateTime转long类型的timestamp(一步到位): 1621908333726

3.6.6、long类型的timestamp转LocalDateTime

/**
 * long类型的timestamp转LocalDateTime
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void timestampToLocalDateTime(){
	//注意timestampLongValue后面有一个L,具体的说明上面事例有说明
	long timestampLongValue= 1621907758486L;
	Instant instant = Instant.ofEpochMilli(timestampLongValue);
	ZoneId zone = ZoneId.systemDefault();
	LocalDateTime l = LocalDateTime.ofInstant(instant, zone);
	System.out.println("long类型的timestamp转LocalDateTime(分步计算):"+l);
	//一步到位的写法(推荐使用)
	LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestampLongValue), ZoneId.systemDefault());
	System.out.println("long类型的timestamp转LocalDateTime(一步到位):"+localDateTime);
}

运行结果:

long类型的timestamp转LocalDateTime(分步计算):2021-05-25T09:55:58.486
long类型的timestamp转LocalDateTime(一步到位):2021-05-25T09:55:58.486

3.6.7、localDate转Date

/**
 * localDate转Date
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void localDateToDate(){
	LocalDate localDate = LocalDate.of(2021,6,18);
	Instant instant = localDate.atStartOfDay(ZoneId.systemDefault()).toInstant();
	Date date = Date.from(instant);
	System.out.println("localDate转Date :"+date);
}

运行结果:

localDate转Date :Fri Jun 18 00:00:00 CST 2021

3.6.8、Date转localDate

/**
 * Date转localDate
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void dateToLocalDate(){
	Date date=new Date();
	Instant instant = date.toInstant();
	LocalDate localDate = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).toLocalDate();
	System.out.println("Date转localDate: "+localDate);
}

运行结果:

Date转localDate: 2021-05-25	

3.6.9、LocalDateTime 转 LocalDate

LocalDate localDate9 = LocalDateTime.now().toLocalDate();

3.6.10、LocalDateTime 转 LocalTime

 LocalTime localTime1 = LocalDateTime.now().toLocalTime();  

3.6.11、LocalDate 转 LocalDateTime

LocalDateTime todayStart = LocalDate.now().atStartOfDay();

3.7 两个时间的毫秒或者纳秒差

/**
 * 计算时间的毫秒或者纳秒差
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void calculateTimeDifference() throws InterruptedException {
	//获取当前时间作为开始时间
	LocalDateTime startTime = LocalDateTime.now();
	//为了测试,我休眠下10毫秒
	Thread.sleep(10);
	//再获取当前时间
	LocalDateTime endTime = LocalDateTime.now();
	System.out.println("开始时间"+startTime+",结束时间"+endTime);
	long millis= ChronoUnit.MILLIS.between(startTime, endTime);
	long nanos = ChronoUnit.NANOS.between(startTime, endTime);
	System.out.println("两个时间的毫秒差:"+millis);
	System.out.println("两个时间的纳秒差:"+nanos);
}

运行结果:

开始时间:2021-05-25T16:21:25.052,结束时间:2021-05-25T16:21:25.064
两个时间的毫秒差:12
两个时间的纳秒差:12000000

3.8 获取指定日期的开始结束时间

/**
 * 获取指定日期的开始时间及结束时间
 * 此处单元测试的注解是采用:org.junit.Test
 */
@Test
public void startTimeOrEndTime(){
	LocalDate date = LocalDate.of(2021,5,20);
	//获取指定日期的开始时间
	LocalDateTime startDateTime = LocalDateTime.of(date, LocalTime.MIN);
	System.out.println("获取到的开始时间"+startDateTime);
	//获取指定日期的结束时间
	LocalDateTime endDateTime = LocalDateTime.of(date, LocalTime.MAX);
	System.out.println("获取到的结束时间"+endDateTime);
}

运行结果:

获取到的开始时间2021-05-20T00:00
获取到的结束时间2021-05-20T23:59:59.999999999

 

 

参考:

Java8新特性:LocalDateTime详细介绍