JDK1.8新特性---新时间日期API

以下内容均来自如下参考链接:

jdk8之前日期时间相关的操作大多用的是Date类或者Calendar类,例如:

 Date date = new Date();
 SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 System.out.println(formatter.format(date)); // 2022-09-18 22:50:58

Date类或者Calendar类的缺点:

  • 非线程安全 : java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java的日期类最大的问题之一。

  • 设计很差 :Java的日期时间类的定义并不一致,在 java.util 和 java.sql 的包中都有日期类,此外用于格式化和解析的类在 java.text 包中定义。java.util.Date同时包含日期和时间,而 java.sql.Date仅包含日期,将其纳入java.sql包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计。

  • 时区处理麻烦 : 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar 和 java.util.TimeZone 类,但他们同样存在上述所有的问题。jd8以后增加了 LocalDate和 Zoned,能更方便优雅的处理日期时间。

       因为原本的Date(jdk1.0提出)、Calendar(jdk1.1提出)使用起来比较困难,即使Calendar类在Date类的基础上改善,但是使用起来还是很麻烦的,所以,在jdk1.8的时候就提出了一些新的时间日期API。

1. java.time包

       java.time包是在第三方包joda包中的joda-Time的基础上吸收了joda-Time的精华而创建出的,并且在Date类中新增了toInstant()方法,用于将Date转换成新的形式(其实也就是转换成为瞬时,也就是Instant类的对象)。

       包含值对象的基础包 (简记为基础包),在java.time包中的时间日期类纠正了过去Date类和Calendar类中的缺陷,所以在将来很长一段时间内可能都会使用java.time包中的类,这个包中最常用的三个类就是LocalDateTime类、LocalDate类、LocalTime类

1.1 LocalDateTime类(本地日期时间类)

包含年月日时分秒,当日期和时间都需要使用时可以使用LocalDateTime

(LocalDateTime相当于LocalDate + LocalTime的合体)

 package timeAPI;
 ​
 import java.text.SimpleDateFormat;
 import java.time.*;
 import java.util.Date;
 ​
 /**
  * @ClassName LocalDateTimeAPI
  * @Description TODO
  * @Author Jiangnan Cui
  * @Date 2022/9/18 22:35
  * @Version 1.0
  */
 public class LocalDateTimeAPI {
     public static void main(String[] args) {
         Date date = new Date();
         SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         System.out.println(formatter.format(date));
 ​
         // 获取当前日期时间:2022-09-18T22:37:32.623
         LocalDateTime nowDateTime = LocalDateTime.now();
         System.out.println("nowDateTime = " + nowDateTime);
 ​
         // 获取当前日期:2022-09-18
         LocalDate localDate = nowDateTime.toLocalDate();
         System.out.println("localDate = " + localDate);
 ​
         // 获取当前时间:22:40:06.052
         LocalTime localTime = nowDateTime.toLocalTime();
         System.out.println("localTime = " + localTime);
 ​
         // 获得当前年份:2022
         int year = nowDateTime.getYear();
         System.out.println("year = " + year);
 ​
         // 获得当前月份:SEPTEMBER
         Month month = nowDateTime.getMonth();
         System.out.println("month = " + month);
         int monthValue = nowDateTime.getMonth().getValue();
         System.out.println("monthValue = " + monthValue);// 9
 ​
         // 获得当前天为该年中的第几天:261
         int dayOfYear = nowDateTime.getDayOfYear();
         System.out.println("dayOfYear = " + dayOfYear);
 ​
         // 获得当前天为该月中的第几天:18
         int dayOfMonth = nowDateTime.getDayOfMonth();
         System.out.println("dayOfMonth = " + dayOfMonth);
 ​
         // 获得当前天为该星期中的第几天:SUNDAY
         DayOfWeek dayOfWeek = nowDateTime.getDayOfWeek();
         System.out.println("dayOfWeek = " + dayOfWeek);
         int dayWeek = nowDateTime.getDayOfWeek().getValue();
         System.out.println("dayWeek = " + dayWeek);// 7
 ​
         // 获得当前小时:22
         int hour = nowDateTime.getHour();
         System.out.println("hour = " + hour);
 ​
         // 获得当前分钟:46
         int minute = nowDateTime.getMinute();
         System.out.println("minute = " + minute);
 ​
         // 获得当前秒数:13
         int second = nowDateTime.getSecond();
         System.out.println("second = " + second);
     }
 }

1.2 LocalDate类(本地日期类)

只包含年月日,不包含时分秒,当不需要具体的时间时可以使用LocalDate

 package timeAPI;
 ​
 import java.time.DayOfWeek;
 import java.time.LocalDate;
 import java.time.Month;
 ​
 /**
  * @ClassName LocalDateAPI
  * @Description TODO
  * @Author Jiangnan Cui
  * @Date 2022/9/18 22:59
  * @Version 1.0
  */
 public class LocalDateAPI {
     public static void main(String[] args) {
         // 获得当前日期:2022-09-18
         LocalDate nowDate = LocalDate.now();
         System.out.println("nowDate = " + nowDate);
 ​
         // 获得年份:2022
         int year = nowDate.getYear();
         System.out.println("year = " + year);
 ​
         // 获得月份:SEPTEMBER
         Month month = nowDate.getMonth();
         System.out.println("month = " + month);
         int monthValue = nowDate.getMonth().getValue();
         System.out.println("monthValue = " + monthValue);// 9
         int monthValue1 = nowDate.getMonthValue();
         System.out.println("monthValue1 = " + monthValue1);// 9
 ​
         // 今天为该年中的第几天:261
         int dayOfYear = nowDate.getDayOfYear();
         System.out.println("dayOfYear = " + dayOfYear);
 ​
         // 今天为该月中的第几天:18
         int dayOfMonth = nowDate.getDayOfMonth();
         System.out.println("dayOfMonth = " + dayOfMonth);
 ​
         // 今天为该周中的星期几:SUNDAY
         DayOfWeek dayOfWeek = nowDate.getDayOfWeek();
         System.out.println("dayOfWeek = " + dayOfWeek);
         int dayWeek = nowDate.getDayOfWeek().getValue();
         System.out.println("dayWeek = " + dayWeek);// 7
     }
 }

1.3 LocalTime类(本地时间类)

只包含时分秒,不包含年月日,当不需要具体的日期时可以使用LocalTime

 package timeAPI;
 ​
 import java.time.LocalTime;
 ​
 /**
  * @ClassName LocalTimeAPI
  * @Description TODO
  * @Author Jiangnan Cui
  * @Date 2022/9/18 23:08
  * @Version 1.0
  */
 public class LocalTimeAPI {
     public static void main(String[] args) {
         // 获得当前时间:23:09:09.294
         LocalTime nowTime = LocalTime.now();
         System.out.println("nowTime = " + nowTime);
 ​
         // 获得当前小时:23
         int hour = nowTime.getHour();
         System.out.println("hour = " + hour);
 ​
         // 获得当前分钟:10
         int minute = nowTime.getMinute();
         System.out.println("minute = " + minute);
 ​
         // 获得当前秒数:51
         int second = nowTime.getSecond();
         System.out.println("second = " + second);
     }
 }

1.4 ZonedDateTime类(时区类)

参考链接:ZonedDateTime类_窝在小角落里学习的博客-CSDN博客_zoneddatetime

       因为LocalDateTime没有时区,无法确定某一时刻,导致LocalDateTime无法与时间戳进行转换。其实LocalDateTime和ZonedDateTime很相似,区别只是LocalDateTime总是表示本地日期和时间,而ZonedDateTime要表示一个带时区的日期和时间。

       我们可以简单地把ZonedDateTime理解成LocalDateTime + ZoneId。ZoneId是java.time引入的新的时区类,注意和旧的java.util.TimeZone区别。

ZonedDateTime类的常用方法如下:

 //从默认时区中的系统时钟中获取当前日期时间
 static ZonedDateTime now() 
 ​
 //从指定的时钟中获取当前日期时间
 static ZonedDateTime now(Clock clock) 
  
 //从指定时区中的系统时钟中获得当前日期时间  
 static ZonedDateTime now(ZoneId zone) 
 ​
 //获得 ZonedDateTime实例从年,月,日,小时,分钟,秒,纳秒和时区
 static ZonedDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond, ZoneId zone) 
   
 //获得 ZonedDateTime实例从本地日期和时间
 static ZonedDateTime of(LocalDate date, LocalTime time, ZoneId zone) 
  
 //获得 ZonedDateTime实例从本地日期时间
 static ZonedDateTime of(LocalDateTime localDateTime, ZoneId zone) 
   
 //获得 ZonedDateTime实例从一个文本字符串,如 2007-12-03T10:15:30+01:00[Europe/Paris]
 static ZonedDateTime parse(CharSequence text) 
 ​
 //获得 ZonedDateTime实例从使用特定格式的文本字符串
 static ZonedDateTime parse(CharSequence text, DateTimeFormatter formatter) 
 ​
 //返回此日期时间的副本,以不同的时区,保留即时
 ZonedDateTime withZoneSameInstant(ZoneId zone)

注意:LocalDateTime类也提供了一个方法来获取ZonedDateTime对象

 //结合时间与时区来创建一个 ZonedDateTime
 ZonedDateTime atZone(ZoneId zone)

举例:

 package timeAPI;
 ​
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
 ​
 /**
  * @ClassName ZonedDateTimeTest
  * @Description TODO
  * @Author Jiangnan Cui
  * @Date 2022/9/21 20:19
  * @Version 1.0
  */
 public class ZonedDateTimeTest {
     public static void main(String[] args) {
         // 从默认时区中的系统时钟中获取当前日期时间:2022-09-21T20:23:16.600+08:00[Asia/Shanghai]
         ZonedDateTime nowZonedDateTime = ZonedDateTime.now();
         System.out.println("nowZonedDateTime = " + nowZonedDateTime);
 ​
         // 获得指定时区的当前日期时间:2022-09-21T08:23:16.601-04:00[America/New_York]
         ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("America/New_York"));
         System.out.println("zonedDateTime = " + zonedDateTime);
 ​
         // 获得指定时间指定时区的日期时间
         LocalDateTime localDateTime = LocalDateTime.of(2022, 11, 11, 22, 22, 22);
         System.out.println("localDateTime = " + localDateTime);// 2022-11-11T22:22:22
         ZonedDateTime zonedDateTime1 = ZonedDateTime.of(localDateTime, ZoneId.of("America/New_York"));
         System.out.println("zonedDateTime1 = " + zonedDateTime1);// 2022-11-11T22:22:22-05:00[America/New_York]
 ​
         // LocalDateTime.atZone()方法: 获得指定时间默认时区与指定时区的日期时间
         ZonedDateTime zonedDateTime2 = localDateTime.atZone(ZoneId.systemDefault());
         System.out.println("zonedDateTime2 = " + zonedDateTime2);// 2022-11-11T22:22:22+08:00[Asia/Shanghai]
         ZonedDateTime zonedDateTime3 = localDateTime.atZone(ZoneId.of("America/New_York"));
         System.out.println("zonedDateTime3 = " + zonedDateTime3);// 2022-11-11T22:22:22-05:00[America/New_York]
 ​
 ​
         /**
          * 时区转换
          */
         LocalDateTime dateTime = LocalDateTime.of(2020, 2, 2, 22, 22, 22);
         System.out.println("dateTime = " + dateTime);// 2020-02-02T22:22:22
         ZonedDateTime zoneTime = ZonedDateTime.of(dateTime, ZoneId.of("Asia/Shanghai"));
         System.out.println("zoneTime = " + zoneTime);// 2020-02-02T22:22:22+08:00[Asia/Shanghai]
         ZonedDateTime zoneTime2 = zoneTime.withZoneSameInstant(ZoneId.of("America/New_York"));
         System.out.println("zoneTime2 = " + zoneTime2);// 2020-02-02T09:22:22-05:00[America/New_York]
     }
 }

1.5 Duration类(持续时间类)

参考链接:

       在JDK8中,可以使用java.time.Duration来计算两个时间之间的时间差,可用于LocalDateTime之间的比较,也可用于Instant之间的比较,这个类是不可变的、线程安全的、最终类。

       Duration类通过秒和纳秒相结合来描述一个时间量,最高精度是纳秒。时间量可以为正也可以为负,比如1天(86400秒0纳秒)、-1天(-86400秒0纳秒)、1年(31556952秒0纳秒)、1毫秒(0秒1000000纳秒)等。

1.5.1 创建方法

(1)通过时间单位创建

       基于天、时、分、秒、毫秒、纳秒创建:ofDays()、ofHours()、ofMinutes()、ofSeconds()、ofMillis()、ofNanos()。例如:

 Duration fromDays = Duration.ofDays(1);

(2)通过LocalDateTime或LocalTime

       通过LocalDateTime或者LocalTime 类,然后使用between获取创建Duration。

 LocalDateTime start = LocalDateTime.of(2022, 1, 1, 8, 0, 0);
 LocalDateTime end = LocalDateTime.of(2022, 1, 2, 8, 30, 30);
 Duration duration = Duration.between(start, end);

(3)通过已有的Duration

 Duration du1 = Duration.ofHours(10);
 Duration duration = Duration.from(du1);

1.5.2 解析方法

       Duration采用ISO-8601时间格式,格式为:PnYnMnDTnHnMnS (n为个数),其中,"P", "D", "H", "M" 和 "S"可以是大写或者小写,建议大写,可以用“-”表示负数。

 Duration fromChar1 = Duration.parse("P1DT1H10M10.5S");
 Duration fromChar2 = Duration.parse("PT10M");

例如:P1Y2M10DT2H30M15.03S

P:开始标记

1Y:一年

2M:两个月

10D:十天

T:日期和时间的分割标记

2H:两个小时

30M:三十分钟

15.03S:15.03秒

其他举例:

 "PT20.345S" -- parses as "20.345 seconds"
 "PT15M"     -- parses as "15 minutes" (where a minute is 60 seconds)
 "PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
 "P2D"       -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
 "P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
 "P-6H3M"    -- parses as "-6 hours and +3 minutes"
 "-P6H3M"    -- parses as "-6 hours and -3 minutes"
 "-P-6H+3M"  -- parses as "+6 hours and -3 minutes"

1.5.3 计算两个时间之间的时间差

 package timeAPI;
 ​
 import java.io.BufferedWriter;
 import java.time.Duration;
 import java.time.LocalDateTime;
 ​
 /**
  * @ClassName DurationTest
  * @Description TODO
  * @Author Jiangnan Cui
  * @Date 2022/9/21 21:21
  * @Version 1.0
  */
 public class DurationTest {
     public static void main(String[] args) {
         // 获得当前日期时间
         LocalDateTime nowDateTime = LocalDateTime.now();
         System.out.println("nowDateTime = " + nowDateTime);
 ​
         // 指定日期时间
         LocalDateTime oldDateTime = LocalDateTime.of(2020, 10, 10, 10, 10, 10);
         System.out.println("oldDateTime = " + oldDateTime);
 ​
         // 计算两个时间的时间差 Duration.between(start, end):start - end
         Duration between = Duration.between(oldDateTime, nowDateTime);
         System.out.println("between = " + between);
 ​
         // 任何一个时间单元为负数,则返回true,即end早于start
         //               正数,  返回false,即end晚于start
         boolean negative = between.isNegative();
         System.out.println("negative = " + negative);
 ​
 ​
         // toX用来转换为其他单位,支持:toDays, toHours, toMinutes, toMillis, toNanos
         // 两个时间之间的时间差转换为天数
         System.out.println("between.toDays() = " + between.toDays());
 ​
         // 两个时间之间的时间差转换为小时数
         System.out.println("between.toHours() = " + between.toHours());
 ​
         // 两个时间之间的时间差转换为分钟数
         System.out.println("between.toMinutes() = " + between.toMinutes());
         // 两个时间之间的时间差转换为毫秒数
         System.out.println("between.toMillis() = " + between.toMillis());
 ​
         // 两个时间之间的时间差转换为纳秒数
         System.out.println("between.toNanos() = " + between.toNanos());
 ​
 ​
         // 可以用getX来获得指定位置的值,因为Duration是由秒和纳秒组成,所以只能获得秒和纳秒
         // 获得两个时间差中的秒数
         long seconds = between.getSeconds();
         System.out.println("seconds = " + seconds);
 ​
         // 获得两个时间差中的纳秒数
         int nano = between.getNano();
         System.out.println("nano = " + nano);
     }
 }

输出结果:

 nowDateTime = 2022-09-21T23:32:01.592
 oldDateTime = 2020-10-10T10:10:10
 between = PT17077H21M51.592S
 negative = false
 between.toDays() = 711
 between.toHours() = 17077
 between.toMinutes() = 1024641
 between.toMillis() = 61478511592
 between.toNanos() = 61478511592000000
 seconds = 61478511
 nano = 592000000

1.5.4 增减方法

  • plusX()、minusX():X表示days, hours, millis, minutes, nanos 或 seconds

 Duration duration = Duration.ofHours(2);
 Duration newDuration = duration.plusSeconds(33);
  • plus()/minus()方法:带TemporalUnit 类型参数进行加减

 Duration duration = Duration.ofHours(2);
 Duration newDuration = duration.plus(33, ChronoUnit.SECONDS);

1.6 Period类

参考链接:https://www.jb51.net/article/249084.htm

       Duration类通过秒和纳秒相结合来描述一个时间量,最高精度是纳秒。时间量可以为正也可以为负,比如1天(86400秒0纳秒)、-1天(-86400秒0纳秒)、1年(31556952秒0纳秒)、1毫秒(0秒1000000纳秒)等。

       Period类通过年、月、日相结合来描述一个时间量,最高精度是天。时间量可以为正也可以为负,例如2年(2年0个月0天)、3个月(0年3个月0天)、4天(0年0月4天)等。

       这两个类是不可变的、线程安全的、最终类。都是JDK8新增的。

1.6.1 创建方法

(1)通过时间单位创建

如果仅一个值表示,如使用ofDays()方法,那么其他值为0。

若仅用ofWeeks,则其天数为week数乘以7.

 Period fromUnits = Period.of(3, 10, 10);
 Period fromDays = Period.ofDays(50);
 Period fromMonths = Period.ofMonths(5);
 Period fromYears = Period.ofYears(10);
 Period fromWeeks = Period.ofWeeks(40);  //280天

(2)通过LocalDate创建

 LocalDate startDate = LocalDate.of(2015, 2, 20);
 LocalDate endDate = LocalDate.of(2017, 1, 15);
 // startDate减endDate
 Period period = Period.between(startDate, endDate);

1.6.2 解析方法

格式1:“PnYnMnWnD”

P:开始符,表示period(即:表示年月日);

Y:year;

M:month;

W:week;

D:day

P, Y, M, W, D都可以用大写或者小写。

 Period period = Period.parse("P2Y");       //2年
 Period period = Period.parse("P2Y3M5D");   //2年3月5天
 Period period = Period.parse("P1Y2M3W4D"); // 1年2月3周4天。即:1年2月25天

获得年月日:

 period.getYears();
 period.getMonths();
 period.getDays();

1.6.3 比较方法(between)

 LocalDate startDate = LocalDate.of(2015, 2, 20);
 LocalDate endDate = LocalDate.of(2017, 1, 15);
 // startDate减endDate
 Period period = Period.between(startDate, endDate);
 // 任何一个时间单元为负数,则返回true,表示endDate早于startDate
 period.isNegative()

1.6.4 增减方法

 Period period = Period.parse("P2Y3M5D");
 period.plusDays(50);
 period.minusMonths(2);

1.6.5 转换单位

 Period period = Period.parse("P1Y2M3D");
 period.toTotalMonths(); // 14

1.6.6 取值方法

 Period period = Period.parse("P1Y2M3D");
 period.getYears();  // 1
 period.getMonths(); // 2
 period.getDays();   // 3

1.7 创建指定日期时间

 package timeAPI;
 ​
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 ​
 /**
  * @ClassName CreateDateTime
  * @Description TODO
  * @Author Jiangnan Cui
  * @Date 2022/9/18 23:50
  * @Version 1.0
  */
 public class CreateDateTime {
     public static void main(String[] args) {
         LocalDateTime ofDateTime = LocalDateTime.of(2022, 9, 18, 23, 59, 59);
         System.out.println("ofDateTime = " + ofDateTime);// 2022-09-18T23:59:59
 ​
         LocalDate ofDate = LocalDate.of(2022, 9, 18);
         System.out.println("ofDate = " + ofDate);// 2022-09-18
 ​
         LocalTime ofTime = LocalTime.of(23, 59, 59);
         System.out.println("ofTime = " + ofTime);// 23:59:59
     }
 }

1.8 日期时间加减及相关运算

 package timeAPI;
 ​
 import java.time.*;
 import java.time.chrono.IsoChronology;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.TemporalAdjusters;
 ​
 import static java.time.temporal.ChronoUnit.*;
 ​
 public class DateTimeOperate {
     public static void main(String[] args) {
         /**
          * 日期时间加减
          */
         LocalDateTime localDateTime = LocalDateTime.now();
         System.out.println("localDateTime = " + localDateTime);// 2022-09-19T19:58:10.146
 ​
         // 日期时间加法运算
         LocalDateTime localDateTime1 = localDateTime.plusYears(1).plusMonths(2).plusDays(3).plusHours(4).plusMinutes(5).plusSeconds(6);
         System.out.println("localDateTime1 = " + localDateTime1);// 2023-11-23T00:03:16.146
 ​
         // 日期时间减法运算
         LocalDateTime localDateTime2 = localDateTime.minusYears(1).minusMonths(2).minusDays(3).minusHours(4).minusMinutes(5).minusSeconds(6);
         System.out.println("localDateTime2 = " + localDateTime2);// 2021-07-16T15:53:04.146
 ​
         // ChronoUnit下类似ChronoUnit.DAYS的还有很多:ChronoUnit.YEARS、ChronoUnit.MONTHS、ChronoUnit.WEEKS等
         LocalDateTime localDateTime3 = localDateTime2.plus(1, ChronoUnit.YEARS);
         System.out.println("localDateTime3 = " + localDateTime3);
         LocalDateTime localDateTime4 = localDateTime2.minus(1, ChronoUnit.YEARS);
         System.out.println("localDateTime4 = " + localDateTime4);
 ​
 ​
         /**
          * 日期加减
          */
         LocalDate localDate = LocalDate.now();
         System.out.println("localDate = " + localDate);// 2022-09-19
 ​
         // 日期加法运算
         LocalDate localDate1 = localDate.plusYears(1).plusMonths(2).plusDays(3).plusWeeks(4);
         System.out.println("localDate1 = " + localDate1);// 2023-12-20
 ​
         // 日期减法运算
         LocalDate localDate2 = localDate.minusYears(1).minusMonths(2).minusDays(3).minusWeeks(4);
         System.out.println("localDate2 = " + localDate2);// 2021-06-18
 ​
         // ChronoUnit下类似ChronoUnit.DAYS的还有很多:ChronoUnit.YEARS、ChronoUnit.MONTHS、ChronoUnit.WEEKS等
         LocalDate localDate3 = localDate2.plus(1, ChronoUnit.DAYS);
         System.out.println("localDate3 = " + localDate3);// 2021-06-19
         LocalDate localDate4 = localDate3.plus(-1, ChronoUnit.DAYS);
         System.out.println("localDate4 = " + localDate4);// 2021-06-18
 ​
         
         /**
          * 时间加减
          */
         LocalTime localTime = LocalTime.now();
         System.out.println("localTime = " + localTime);// 20:10:36.512
 ​
         // 时间加法运算
         LocalTime localTime1 = localTime.plusHours(1).plusMinutes(2).plusSeconds(3);
         System.out.println("localTime1 = " + localTime1);// 21:12:39.512
 ​
         // 时间减法运算
         LocalTime localTime2 = localTime.minusHours(1).minusMinutes(2).minusSeconds(3);
         System.out.println("localTime2 = " + localTime2);// 19:08:33.512
 ​
         // ChronoUnit下类似ChronoUnit.DAYS的还有很多:ChronoUnit.YEARS、ChronoUnit.MONTHS、ChronoUnit.WEEKS等
         LocalTime localTime3 = localTime2.plus(1, HOURS);
         System.out.println("localTime3 = " + localTime3);
         LocalDateTime localTime4 = localDateTime2.minus(1, HOURS);
         System.out.println("localTime4 = " + localTime4);
 ​
         // 计算两个时间时间的时间差
         long betweenHour = HOURS.between(localTime1, localTime2);
         System.out.println("betweenHour = " + betweenHour);
         long betweenMinute = MINUTES.between(localTime1, localTime2);
         System.out.println("betweenMinute = " + betweenMinute);
         long betweenSecond = SECONDS.between(localTime1, localTime2);
         System.out.println("betweenSecond = " + betweenSecond);
 ​
 ​
         /**
          * 比较日期的先后
          */
         LocalDate nowDate = LocalDate.now();
         System.out.println("nowDate = " + nowDate);// 2022-09-19
 ​
         LocalDate date = LocalDate.of(2022, 9, 18);
         System.out.println("date = " + date);// 2022-09-18
 ​
         boolean equal = nowDate.isEqual(date);
         System.out.println("equal = " + equal);// false
 ​
         boolean before = nowDate.isBefore(date);
         System.out.println("before = " + before);// false
 ​
         boolean after = nowDate.isAfter(date);
         System.out.println("after = " + after);// true
 ​
         // -1表示早于,0表示相等,1表示晚于
         int i = nowDate.compareTo(date);
         System.out.println("i = " + i);// 1
 ​
         // 判断日期1是否早于日期2,早于返回false,晚于返回true
         Period period = Period.between(nowDate, date);
         System.out.println("period = " + period);// P-1D
         boolean periodNegative = period.isNegative();
         System.out.println("periodNegative = " + periodNegative);// true
         boolean periodZero = period.isZero();
         System.out.println("periodZero = " + periodZero);// false
 ​
         boolean supported = nowDate.isSupported(ChronoUnit.DAYS);
         System.out.println("supported = " + supported);// true
 ​
 ​
         /**
          * 判断平闰年
          */
         // 指定年份判断平闰年
         boolean leapYear1 = IsoChronology.INSTANCE.isLeapYear(2000);
         System.out.println("leapYear1 = " + leapYear1);// true
 ​
         // localDateTime.getYear()
         boolean leap = Year.isLeap(localDateTime4.getYear());
         System.out.println("leap = " + leap);// false
 ​
         // localDate.getYear()
         boolean leap1 = Year.isLeap(localDate.getYear());
         System.out.println("leap1 = " + leap1);// false
 ​
         // localDate.isLeapYear()
         boolean leapYear = nowDate.isLeapYear();
         System.out.println("leapYear = " + leapYear);// false
 ​
 ​
         /**
          * 计算指定日期所在月份的天数
          */
         int monthDays = nowDate.lengthOfMonth();
         System.out.println("monthDays = " + monthDays);// 30
 ​
         /**
          * 计算指定日期所在年份的天数
          */
         int yearDays = nowDate.lengthOfYear();
         System.out.println("yearDays = " + yearDays);// 365
 ​
         /**
          * 判断今天是不是星期一
          */
         boolean isMonday = LocalDate.now().getDayOfWeek() == DayOfWeek.MONDAY;
         System.out.println(isMonday);
 ​
         /**
          * 获取日期所在月份的最后一天
          */
         LocalDate lastDayOfMonth = nowDate.with(TemporalAdjusters.lastDayOfMonth());
         System.out.println("lastDayOfMonth = " + lastDayOfMonth);
 ​
 ​
         /**
          * 计算两个日期之间的时间间隔
          */
         long untilYear = nowDate.until(date, YEARS);
         System.out.println("untilYear = " + untilYear);
         long untilMonth = nowDate.until(date, MONTHS);
         System.out.println("untilMonth = " + untilMonth);
         long untilDay = nowDate.until(date, DAYS);
         System.out.println("untilDay = " + untilDay);
 ​
         Period periodDate = Period.between(nowDate, date);
         System.out.println("periodDate = " + periodDate);
         int periodDateYears = periodDate.getYears();
         System.out.println("periodDateYears = " + periodDateYears);
         int periodDateMonths = periodDate.getMonths();
         System.out.println("periodDateMonths = " + periodDateMonths);
         int periodDateDays = periodDate.getDays();
         System.out.println("periodDateDays = " + periodDateDays);
 ​
         /**
          * MonthDay表示月与日的组合
          */
         MonthDay monthDay = MonthDay.now();
         System.out.println(monthDay.getDayOfMonth());// 今天是这个月的第几天:19
         System.out.println(monthDay.getMonth());// 今天是几月:SEPTEMBER
         LocalDate monthDayDate = monthDay.atYear(2022);// 指定年份
         System.out.println(monthDayDate);// 2022-09-19
 ​
         /**
          * 计算生日
          */
         LocalDate birthDate = LocalDate.of(2020,02,02);
         MonthDay birthdayMonthDay = MonthDay.of(birthDate.getMonth(), birthDate.getDayOfMonth());
         MonthDay currentMonthDay = MonthDay.from(nowDate);// //LocalDate格式换转换为MonthDay
         if(currentMonthDay.equals(birthdayMonthDay)){
             System.out.println("陌生人,生日快乐!");
         }else{
             System.out.println("不着急,再等等,下次我们陪你一起过生日!");
         }
     }
 }

1.9 Clock时间戳与其他时区时间

       Java 8 增加了一个 Clock 时钟类用于获取当时的时间戳,或当前时区下的日期时间信息。以前用到System.currentTimeInMillis() 和 TimeZone.getDefault() 的地方都可用 Clock 替换。

  • 获取时间戳:

 //获取时间戳方法1
 Instant timestamp = Instant.now();
 System.out.println("Instant获取时间戳:" + timestamp.toEpochMilli());
 ​
 //获取时间戳方法2
 Clock clock = Clock.systemUTC();
 System.out.println("Clock时间戳 : " + clock.millis());
 ​
 //获取时间戳方法3
 Clock defaultClock = Clock.systemDefaultZone();
 System.out.println("defaultClock时间戳: " + defaultClock.millis());

输出结果:

 Instant获取时间戳:1663602236877
 Clock时间戳 : 1663602236877
 defaultClock时间戳: 1663602236877

       无论是使用Clock.systemUTC或者Clock.systemDefaultZone获得的时间戳都是一样的,区别在于Clock.systemUTC返回的时钟的区域为UTC时区,Clock.systemDefaultZone返回的是你所在国家的时区,所以如果你还要把你的时间戳转换成LocalDateTime这样具体的年月日时分秒,那你就应该用Clock.systemDefaultZone。

  • 时间戳转LocalDateTime:

 Clock defaultClock = Clock.systemDefaultZone();
 System.out.println("当前时间戳 : " + defaultClock.millis());
 LocalDateTime data1 = LocalDateTime.now(defaultClock);
 System.out.println("时间戳转化为时间" + data1.toString());

输出结果:

 当前时间戳 : 1663602365479
 时间戳转化为时间2022-09-19T23:46:05.479
  • 获取巴黎的当前时间:

 Clock clock = Clock.system(ZoneId.of("Europe/Paris")); // 指定巴黎时区
 System.out.println("巴黎当前时间戳 : " + clock.millis());
 LocalDateTime data=LocalDateTime.now(clock);
 System.out.println("巴黎当前时间" + data.toString());

输出结果:

 巴黎当前时间戳 : 1663602517128
 巴黎当前时间2022-09-19T17:48:37.128

时间戳测试:​​​​​​​

 public class TimeStampTest {
     public static void main(String[] args) {
         /**
          *  系统时间
          */
         long l = System.currentTimeMillis();
         System.out.println("l = " + l);
         // 1668160031441
 ​
         /**
          * 系统时间转时间戳
          */
         Timestamp t = new Timestamp(System.currentTimeMillis());
         System.out.println("t = " + t);
         // t = 2022-11-14 08:55:05.524
 ​
         /**
          * 时间戳
          */
         Timestamp timestamp = new Timestamp(l);
         System.out.println("timestamp = " + timestamp);
         // timestamp = 2022-11-14 08:55:05.53
 ​
         /**
          * 时间戳.getTime()
          */
         long time = timestamp.getTime();
 ​
         /**
          * 时间戳.getTime()转Date
          */
         Date date = new Date(time);
         System.out.println("date = " + date);
         // date = 2022-11-14
 ​
         /**
          * 时间戳.getTime()转LocalDateTime
          */
         Instant instant = Instant.ofEpochMilli(time);
         LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
         System.out.println("localDateTime = " + localDateTime);
         // localDateTime = 2022-11-14T09:00:39.840
 ​
         /**
          * LocalDateTime转LocalDate
          */
         LocalDate localDate = localDateTime.toLocalDate();
         System.out.println("localDate = " + localDate);
         // localDate = 2022-11-14
 ​
         /**
          * LocalDateTime转LocalTime
          */
         LocalTime localTime = localDateTime.toLocalTime();
         System.out.println("localTime = " + localTime);
         // localTime = 09:04:13.453
     }
 }

2. java.time.format包(格式化和解析时间和日期)

2.1 LocalDateTime格式化

 package timeAPI;
 ​
 import java.time.LocalDateTime;
 import java.time.OffsetDateTime;
 import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 ​
 /**
  * @ClassName DateTimeFormatterTest
  * @Description TODO
  * @Author Jiangnan Cui
  * @Date 2022/9/18 23:13
  * @Version 1.0
  */
 public class LocalDateTimeFormatter {
     public static void main(String[] args) {
         // LocalDateTime格式化
         LocalDateTime localDateTime = LocalDateTime.now();// 2022-09-18T23:18:15.907
         System.out.println("localDateTime = " + localDateTime);
 ​
         DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
         String format = localDateTime.format(dateTimeFormatter);
         System.out.println("format = " + format);// 2022-09-18 23:18:15
 ​
         DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分ss秒");
         String format1 = localDateTime.format(dateTimeFormatter1);
         System.out.println("format1 = " + format1);// 2022年09月18日23时18分15秒
 ​
         String s = localDateTime.toString();
         System.out.println("s = " + s);// 2022-09-18T23:19:12.088
 ​
         // 添加时区
         OffsetDateTime offsetDateTime = localDateTime.atOffset(ZoneOffset.ofHours(+8));
         System.out.println("offsetDateTime = " + offsetDateTime);// 2022-09-18T23:21:12.122+08:00
         String s1 = offsetDateTime.toString();
         System.out.println("s1 = " + s1);// 2022-09-18T23:21:12.122+08:00
 ​
         // 解析字符串: 年月日之间要用-分割,时分秒用:分割,日期和时间之间用T分割
         String dateTimeString ="2022-09-18T23:18:00";
         LocalDateTime parseDateTime = LocalDateTime.parse(dateTimeString);
         System.out.println("parseDateTime = " + parseDateTime);// 2022-09-18T23:18
         // 注意: LocalDateTime当秒数刚好为0的时候格式化后秒会被省略,格式化要指定到秒。
     }
 }

2.2 LocalDate格式化

 package timeAPI;
 ​
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 ​
 /**
  * @ClassName LocalDateFormatter
  * @Description TODO
  * @Author Jiangnan Cui
  * @Date 2022/9/18 23:25
  * @Version 1.0
  */
 public class LocalDateFormatter {
     public static void main(String[] args) {
         LocalDate localDate = LocalDate.now();
         System.out.println("localDate = " + localDate);// 2022-09-18
 ​
         DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
         String format = localDate.format(dateTimeFormatter);
         System.out.println("format = " + format);// 2022年09月18日
 ​
         DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy.MM.dd");
         String format1 = localDate.format(dateTimeFormatter1);
         System.out.println("format1 = " + format1);// 2022.09.18
 ​
         // 解析字符串: 年月日用-分开,月份和日期如果小于10要补零
         String dateString ="2022-09-18";
         LocalDate parseDate = LocalDate.parse(dateString);
         System.out.println("parseDate = " + parseDate);// 2022-09-18
 ​
         dateString = "20220918";
         //除了DateTimeFormatter.BASIC_ISO_DATE格式DateTimeFormatter里还有其他格式可选择
         parseDate = LocalDate.parse(dateString, DateTimeFormatter.BASIC_ISO_DATE);
         System.out.println("parseDate = " + parseDate);// 2022-09-18
     }
 }

2.3 LocalTime格式化

 package timeAPI;
 ​
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 ​
 /**
  * @ClassName LocalTimeFormatter
  * @Description TODO
  * @Author Jiangnan Cui
  * @Date 2022/9/18 23:25
  * @Version 1.0
  */
 public class LocalTimeFormatter {
     public static void main(String[] args) {
         LocalTime localTime = LocalTime.now();
         System.out.println("localTime = " + localTime);// 23:31:00.169
 ​
         DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH-mm-ss");
         String format = localTime.format(dateTimeFormatter);
         System.out.println("format = " + format);// 23-31-00
 ​
         DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("HH时mm分ss秒");
         String format1 = localTime.format(dateTimeFormatter1);
         System.out.println("format1 = " + format1);// 23时31分00秒
 ​
         // 解析字符串: 时分秒用:分开,时分秒如果小于10要补零
         String timeString ="23:18:00";
         LocalTime parseTime = LocalTime.parse(timeString);
         System.out.println("parseTime = " + parseTime);// 23:18
     }
 }

3. java.time.temporal包(底层框架扩展特性)

待完善

4. java.time.chrono包(日历类访问)

待完善

5. java.time.zone包

其中包含了对不同的时区的访问,日期就是年月日,时间就是时分秒 待完善

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值