Java 8新特性 全新的日期时间API

来源:互联网 发布:网络监控软件破解版 编辑:程序博客网 时间:2024/06/05 00:33

Java 8 Date Time AP

Java 8 Date Time AP 是受开发者最受追捧的变更。 java在之前并没有处理日期、时间的一致性方法。

为什么我们需要新的 Java Date Time API?

我们关注Java 8 Date Time API使用之前,先看一下我们为什么需要它们。之前,在与日期、时间关联的java类中存在以下几个问题:

  • java的日期、时间类定义不一致。 之前在 java.util、java.sql包中都定义了Date类;但是格式化个解析类又放在java.text包下。

  • java.util.Date 包含了日期和时间,但是java.sql.Date只包含了日期。 这两个类具有共同的名字,真是糟糕的设计。

  • 对于时间, 时间戳, 格式化和解析并没有清晰定义的java类。 一般使用java.text.DateFormat提供的格式化、解析方法。 通常使用 SimpleDateFormat 类进行格式化日期时间与解析日期时间。

  • 所有的日期类均不是线程安全的。这也是Date 和Calendar类存在的最大问题之一。

  • Date 类没有提供国际化,也不支持时区。

Date 、Calendar还存在其他的问题,但是上述问题已经表明java需要更强大的日期时间API了。这也是为什么 Joda Time 作为Java Date Time的替代者的原因了。

Java 8 Date

Java 8 Date Time API 是 JSR-310的实现。 设计初衷是为了克服固有的Date Time API遗留下来的缺陷。新的Date Time API设计原则:

  • 稳定不变性 新的Date Time API 是线程安全的。

  • 关注点分离 新的API 将人与机器的关注点分离了(二者关注的分别是时间日期、unix时间戳),设计了诸如Date, Time, DateTime, Timestamp, Timezone这些类。

  • 清晰 在众多类中声明了同样动作的方法。例如 now()方法获得当前实例。format()、parse()都在这些类中有定义。而不是分离出来在不同的类中定义。所有这些类设计是按工厂模式、策略模式来进行的,易于操作。一旦你学会使用其中一个类地方法,使用其他类就很简单了。

  • 通用工具方法 所有新的Date Time API 类均提供了常用的方法。加、减、格式、解析以及分离日期和时间等操作。

  • 扩展性 新的Date Time API是基于ISO-8601日历系统设计的,我们也可以采用其他非ISO 日历系统设计。

Java 8 Date Time API 包

Java 8 Date Time API包含以下包:

  • java.time包 这是新的Java Date Time API基础包。 主要的基础类均在这个包中,如 LocalDate, LocalTime, LocalDateTime, Instant, Period, Duration等等。所有这些类均是线程安全的。 大多数情况下,这些类已经能够处理常用操作了。

  • java.time.chrono包 这个包定义了通用的非ISO日历系统的API。我们可以继承AbstractChronology 类扩展我们自定义的日历系统。

  • java.time.format包 这个包包含了格式化、解析时间的类。更多的时候我们并不会用到他们,因为 java.time 包已经提供了日期格式化、解析的方法。

  • java.time.temporal 包 提供了一些获取临时信息的对象。 比如获取当期月的第一或最后一天。你能很好识别这些方法,因为他们通常被命名为“withXXX”。

  • java.time.zone包 支持不同时区和其他规则。

Java 8 Date Time API使用示例

了解新Java Date Time API的重要性之后,我们通过实例来学习Date Time相关的类。

LocalDate

LocalDate 是一个用来表示日期的不可变类(final修饰),默认格式是 yyyy-MM-dd。我们可以通过其now()方法获取当前日期。也提供了可以表示year, month 和 date 入参来获取LocalDate 实例。这个类提供了now()的重载方法通过提供一个时区的入参获取指定时区的日期。这个类的功能和java.sql.Date类似的功能。

package com.byron4j.hightLevel.java8.date;import java.time.LocalDate;import java.time.ZoneId;/** *  * <pre> *  LocalDate示例 * </pre> * @author Byron.Y.Y */public class LocalDateTest {    public static void main(String[] args) {        //获取当前日期默认格式yyyy-MM-d        System.out.println(LocalDate.now().toString());        //使用now()重载方法,ZoneId的of方法使用了其内嵌的时区map映射表        System.out.println(LocalDate.now(ZoneId.of("CTT", ZoneId.SHORT_IDS)));        //获取指定上海时区的日期(时区的id参见ZoneId 类的文档)        System.out.println(LocalDate.now(ZoneId.of("Asia/Shanghai")));        //2017-05-07        System.out.println(LocalDate.of(2017, 5, 7));        //入参为从1970-01-01起的累计天数(1970-01-01为0)        System.out.println(LocalDate.ofEpochDay(17293));        //指定年的第多少天(2017年的第127天是5月7日)        System.out.println(LocalDate.ofYearDay(2017, 127));    }}

编写该代码时是2017-05-07日,所以程序运行结果都是:2017-05-07。

LocalTime

LocalTime 代表了一个人们可读格式的时间实例。

package com.byron4j.hightLevel.java8.date;import java.time.LocalTime;import java.time.ZoneId;/** *  * <pre> *  LocalTime类的示例 * </pre> * @author Byron.Y.Y */public class LocalTimeTest {    public static void main(String[] args) {        //输出格式HH:mm:ss.ms  毫秒        System.out.println(LocalTime.now());        //hour minute second 纳秒        System.out.println(LocalTime.of(20, 53, 30, 70));        System.out.println(LocalTime.now(ZoneId.of("Asia/Shanghai")));        System.out.println(LocalTime.ofSecondOfDay(86399));    }}

输出结果:

20:59:58.91620:53:30.00000007020:59:58.91723:59:59

LocalDateTime

LocalDateTime 代表了日期加时间,默认格式为: yyyy-MM-dd-HH-mm-ss.zzz。它提供了一个工厂方法,使用LocalDate 和LocalTime输入参数构建LocalDateTime实例。

package com.byron4j.hightLevel.java8.date;import java.time.LocalDate;import java.time.LocalDateTime;import java.time.LocalTime;import java.time.ZoneId;/** *  * <pre> *  LocalDateTime演示实例 * </pre> * @author Byron.Y.Y */public class LocalDateTimeTest {    public static void main(String[] args) {        System.out.println(LocalDateTime.now());        System.out.println(LocalDateTime.now(ZoneId.of("Asia/Shanghai")));        //入参LocalDate、LocalTime        System.out.println(LocalDateTime.of(LocalDate.now(), LocalTime.now()));    }}

输出结果:

2017-05-07T21:07:39.7852017-05-07T21:07:39.7862017-05-07T21:07:39.786

Instant

Instant 代表了机器识别格式的实例。存储格式是unix 时间戳。格式形如:2017-05-07T13:12:23.741Z

Java 8 日期格式化和解析

package com.byron4j.hightLevel.java8.date;import java.time.LocalDate;import java.time.format.DateTimeFormatter;/** *  * <pre> *      java8 日期格式化示例 * </pre> * @author Byron.Y.Y */public class DateTimeFormatTest {    public static void main(String[] args) {        LocalDate now = LocalDate.now();        //LocalDate的format仅仅支持日期的格式 不支持小时分秒等格式(否则错误Unsupported field)        System.out.println(now.format(DateTimeFormatter.ofPattern("yyyyMMdd")));        System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_DATE));    }}

输出结果:

20170507
2017-05-07

0 0