一、什么是Java8日期和时间API

Java 8 Date Time API是JSR-310实现。它旨在克服传统日期时间实现中的所有缺陷。新Date Time API的设计原则是:




element 默认时间是今天 el-date-picker默认当前日期_java 当前日期


1、不可变性

新Date Time API中的所有类都是不可变的,适用于多线程环境。

2、关注点分离

新API明确区分人类可读日期时间和机器时间(unix时间戳)。它为Date、Time、DateTime、Timestamp、Timezone等定义了单独的类。

3、清晰度

方法明确定义并在所有类中执行相同的操作。例如,要获取当前实例,我们有now方法。在所有这些类中定义了format和parse方法,而不是为它们设置单独的类。

所有类都使用工厂模式和策略模式来更好地处理。一旦你在其中一个类中使用了这些方法,使用其他类并不难。

4、容易使用

所有新的Date Time API类都带有执行常见任务的方法,例如加号、减号、格式、解析,在日期/时间中获取单独的部分等。

5、可扩展

新的Date Time API适用于ISO-8601日历系统,但我们也可以将其与其他非ISO日历一起使用。

二、为什么需要新的日期和时间API

Java8之前的日期和时间相关类存在一些问题:

1、没有统一定义

在java.util和java.sql包中都有Date类,格式化和解析类又再次定义在java.text包中。

2、java.sql.Date设计糟糕

java.util.Date包含日期和时间,而java.sql.Date仅包含日期,在java.sql包中有Date没有意义。 这两个类都有相同的名称,这本身就是一个非常糟糕的设计。

3、定义不完整

时间,时间戳,格式和解析没有明确定义的类。通常用SimpleDateFormat类用于解析和格式化。

4、非线程安全

所有Date类都是可变的,因此它们不是线程安全的。 这是Java Date和Calendar类最大的问题之一。

5、没有合理的国际化和时区支持

日期类不提供国际化,没有时区支持。 因此引入了java.util.Calendar和java.util.TimeZone类,但它们也具有上面列出的所有问题。


element 默认时间是今天 el-date-picker默认当前日期_element 默认时间是今天_02


三、如何使用新的日期时间API

1、LocalDate

LocalDate是一个不可变类,它表示默认格式为yyyy-MM-dd的Date。

我们可以使用now方法获取当前日期。

我们还可以提供年,月和日的输入参数来创建LocalDate实例。

此类为now提供重载方法,我们可以通过ZoneId获取特定时区的日期。

该类提供与java.sql.Date相同的功能。

示例代码如下:

//当前日期 LocalDate today = LocalDate.now(); System.out.println("Current Date=" + today); //通过输入参数创建日期 LocalDate firstDay_2019 = LocalDate.of(2019, Month.JANUARY, 1); System.out.println("Specific Date=" + firstDay_2019); //通过ZoneId创建日期 LocalDate todayShanghai = LocalDate.now(ZoneId.of("Asia/Shanghai")); System.out.println("Current Date in IST=" + todayShanghai); //从基准日期开始创建日期 LocalDate dateFromBase = LocalDate.ofEpochDay(365); System.out.println("365th day from base date= " + dateFromBase); LocalDate hundredDay2019 = LocalDate.ofYearDay(2019, 100); System.out.println("100th day of 2014=" + hundredDay2019);

2、LocalTime

LocalTime是一个不可变类,其实例表示人类可读格式的时间。 它的默认格式是hh:mm:ss.zzz。 就像LocalDate一样,这个类通过传递小时,分钟和秒作为输入参数来提供时区支持和创建实例。

示例代码如下:

//当前时间 LocalTime time = LocalTime.now(); System.out.println("Current Time=" + time); //通过输入参数创建时间 LocalTime specificTime = LocalTime.of(12, 20, 25, 40); System.out.println("Specific Time of Day=" + specificTime); //通过ZoneId创建时间 LocalTime timeShanghai = LocalTime.now(ZoneId.of("Asia/Shanghai")); System.out.println("Current Time in IST=" + timeShanghai); //通过基准日期创建时间 LocalTime specificSecondTime = LocalTime.ofSecondOfDay(10000); System.out.println("10000th second time= " + specificSecondTime);

3、LocalDateTime

LocalDateTime是一个不可变的日期时间对象,表示日期时间,默认格式为yyyy-MM-dd-HH-mm-ss.zzz。 它提供了一个工厂方法,该方法使用LocalDate和LocalTime输入参数来创建LocalDateTime实例。

示例代码如下:

//当前日期 LocalDateTime today = LocalDateTime.now(); System.out.println("Current DateTime=" + today); //通过LocalDate和LocalTime创建日期 today = LocalDateTime.of(LocalDate.now(), LocalTime.now()); System.out.println("Current DateTime=" + today); //通过输入参数创建日期 LocalDateTime specificDate = LocalDateTime.of(2019, Month.JANUARY, 1, 10, 10, 30); System.out.println("Specific Date=" + specificDate); //通过ZoneId创建日期 LocalDateTime todayShanghai = LocalDateTime.now(ZoneId.of("Asia/Shanghai")); System.out.println("Current Date in IST=" + todayShanghai); //通过基准日期创建日期 LocalDateTime dateFromBase = LocalDateTime.ofEpochSecond(10000, 0, ZoneOffset.UTC); System.out.println("10000th second time from 01/01/1970= " + dateFromBase);

4、Instant

Instant类用于处理机器可读的时间格式,它将日期时间存储在unix时间戳中。

示例代码如下:

//当前时间戳 Instant timestamp = Instant.now(); System.out.println("Current Timestamp = " + timestamp); //通过timestamp创建 Instant specificTime = Instant.ofEpochMilli(timestamp.toEpochMilli()); System.out.println("Specific Time = " + specificTime); //创建Duration Duration thirtyDay = Duration.ofDays(30); System.out.println(thirtyDay);

5、日期工具类

大多数日期时间类提供各种实用方法,例如加/减天,周,月等。

示例代码如下:

LocalDate today = LocalDate.now(); //判断是否是闰年 System.out.println("Year " + today.getYear() + " is Leap Year? " + today.isLeapYear()); //比较日期 System.out.println("Today is before 01/01/2015? " + today.isBefore(LocalDate.of(2015, 1, 1))); //通过LocalTime创建LocalDateTime System.out.println("Current Time=" + today.atTime(LocalTime.now())); //加减操作 System.out.println("10 days after today will be " + today.plusDays(10)); System.out.println("3 weeks after today will be " + today.plusWeeks(3)); System.out.println("20 months after today will be " + today.plusMonths(20)); System.out.println("10 days before today will be " + today.minusDays(10)); System.out.println("3 weeks before today will be " + today.minusWeeks(3)); System.out.println("20 months before today will be " + today.minusMonths(20)); //通过时间调节器调整日期 System.out.println("First date of this month= " + today.with(TemporalAdjusters.firstDayOfMonth())); LocalDate lastDayOfYear = today.with(TemporalAdjusters.lastDayOfYear()); System.out.println("Last date of this year= " + lastDayOfYear); //创建期间 Period period = today.until(lastDayOfYear); System.out.println("Period Format= " + period); System.out.println("Months remaining in the year= " + period.getMonths());

6、日期解析和格式化

将日期格式化为不同格式然后解析String以获取Date Time对象是很常见的。

示例代码如下:

//默认日期格式 LocalDate date = LocalDate.now(); System.out.println("Default format of LocalDate=" + date);  //指定日期格式 System.out.println(date.format(DateTimeFormatter.ofPattern("d::MMM::uuuu"))); System.out.println(date.format(DateTimeFormatter.BASIC_ISO_DATE)); //默认日期格式 LocalDateTime dateTime = LocalDateTime.now(); System.out.println("Default format of LocalDateTime=" + dateTime);  //默认日期时间格式 System.out.println(dateTime.format(DateTimeFormatter.ofPattern("d::MMM::uuuu HH::mm::ss"))); System.out.println(dateTime.format(DateTimeFormatter.BASIC_ISO_DATE)); //默认Instant格式 Instant timestamp = Instant.now(); System.out.println("Default format of Instant=" + timestamp); //字符串解析 LocalDateTime dt = LocalDateTime.parse("27::Apr::2019 21::39::48