Java 8日期– LocalDate,LocalDateTime,即时
对于开发人员而言,Java 8日期时间API是最受欢迎的更改之一。
Java从一开始就缺少一致的Date和Time方法,而Java 8 Date Time API是对核心Java API的欢迎添加。
为什么我们需要新的Java日期时间API?
在开始研究Java 8 Date Time API之前,让我们看看为什么我们需要一个新的API。
Java中与日期和时间相关的现有类存在多个问题,其中一些是:
Java日期时间类的定义不一致,我们在java.util和java.sql包中都有Date类。
再次在java.text包中定义了格式化和解析类。" java.util.Date"包含日期和时间,而" java.sql.Date"仅包含日期。
在java.sql
软件包中包含它是没有意义的。
而且这两个类都具有相同的名称,这本身就是一个很糟糕的设计。没有明确定义的时间,时间戳,格式和解析类。
我们有java.text.DateFormat
抽象类,用于解析和格式化需求。
通常,SimpleDateFormat
类用于解析和格式化。所有的Date类都是可变的,因此它们不是线程安全的。
这是Java日期和日历类的最大问题之一。日期类不提供国际化,没有时区支持。
因此引入了java.util.Calendar和java.util.TimeZone类,但是它们也具有上面列出的所有问题。
Date和Calendar类中定义的方法还存在其他一些问题,但上述问题清楚表明Java中需要强大的Date Time API。
因此,Joda Time在替代Java Date Time要求方面起着重要作用。
Java 8日期
Java 8日期时间API是JSR-310的实现。
它旨在克服传统日期时间实现中的所有缺陷。
新的Date Time API的一些设计原则是:
不变性:新的Date Time API中的所有类都是不变的,并且适用于多线程环境。
关注点分离:新的API明确区分了人类可读的日期时间和机器时间(unix时间戳)。
它为日期,时间,日期时间,时间戳,时区等定义了单独的类。清晰度:方法已明确定义,并在所有类中执行相同的操作。
例如,要获取当前实例,我们可以使用" now()"方法。
在所有这些类中定义了format()和parse()方法,而不是为它们定义单独的类。
所有这些类都使用Factory Pattern和Strategy Pattern进行更好的处理。
一旦在一个类中使用了方法,与其他类一起工作就不会很困难。实用程序操作:所有新的Date Time API类都带有执行常见任务的方法,例如加号,减号,格式,解析,获取日期/时间的单独部分等。
可扩展:新的日期时间API可在ISO-8601日历系统上使用,但我们也可以将其与其他非ISO日历一起使用。
Java 8日期时间API软件包
Java 8日期时间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日期时间API示例
我们已经研究了Java Date Time API的大多数重要部分。
现在该通过示例来研究Date Time API的最重要的类。
- LocalDate
LocalDate
是一个不可变的类,它以默认格式yyyy-MM-dd表示Date。
我们可以使用now()
方法获取当前日期。
我们还可以提供年份,月份和日期的输入参数来创建LocalDate实例。
此类为now()提供了重载的方法,其中我们可以传递ZoneId来获取特定时区中的日期。
此类提供与java.sql.Date
相同的功能。
让我们看一个简单的用法示例。
注释中提供了LocalDate方法的解释,当我们运行此程序时,我们将得到以下输出。
- LocalTimeLocalTime是一个不可变的类,其实例以人类可读的格式表示时间。
默认格式为hh:mm:ss.zzz。
与LocalDate一样,此类提供时区支持并通过传递小时,分钟和秒作为输入参数来创建实例。
让我们用一个简单的程序看看它的用法。
当我们为LocalTime示例运行上述程序时,将得到以下输出。
- LocalDateTime
LocalDateTime
是代表日期时间的不可变日期时间对象,默认格式为yyyy-MM-dd-HH-mm-ss.zzz。
它提供了一个工厂方法,该方法使用LocalDate和LocalTime输入参数来创建LocalDateTime实例。
让我们用一个简单的例子来看看它的用法。
在所有三个示例中,我们已经看到,如果我们提供用于创建Date/Time的无效参数,那么它将抛出java.time.DateTimeException这是RuntimeException,因此我们不需要显式捕获它。
看到我们可以通过传递ZoneId
来获取日期/时间数据,则可以从其javadoc中获取受支持的ZoneId值的列表。
当我们在类上运行时,将得到以下输出。
- InstantInstant类用于使用机器可读的时间格式,它将日期时间存储在UNIX时间戳中。
让我们看看它在一个简单程序中的用法。
上面程序的输出是:
- Java 8 Date API实用程序如前所述,大多数Date Time原理类提供了各种实用程序方法,例如加/减日,周,月等。
还有一些其他实用程序方法,可使用" TemporalAdjuster"来调整日期并计算周期在两个日期之间。
上面程序的输出是:
- Java 8日期解析和格式化很常见的做法是将日期格式化为不同的格式,然后解析字符串以获取日期时间对象。
让我们用简单的例子看一下。
当我们运行上面的程序时,我们得到以下输出。
- Java 8 Date API旧版日期时间SupportLegacy Date/Time类几乎在所有应用程序中使用,因此必须具有向后兼容性。
这就是为什么有几种实用程序方法可以将旧版类转换为新类,反之亦然的原因。
让我们用一个简单的例子来看一下。
当我们在应用程序之上运行时,我们得到以下输出。
如您所见,传统的" TimeZone"和" GregorianCalendar"类的toString()方法过于冗长且不友好。
Java 8 Date Time API就是这样,我非常喜欢这个新API。
一些最常用的类是此新API的LocalDate和LocalDateTime。
使用起来非常简单,并且采用类似的方法来完成特定工作,因此很容易找到。
从传统类到新的日期时间类将需要一些时间,但我相信这是值得的。