JDK8特性-新的日期和时间API
参考文献
旧的日期和时间API的缺点
Date
类的缺点
Date
类中的大多数方法都已经过时,因为它们不是线程安全的,而且有一些设计缺陷.Date
类中的时间表示是基于1970年1月1日的毫秒数,这种表示方式不太方便处理日期和时间.
Calendar
类的缺点
Calendar
类不是线程安全的,如果多个线程同时访问一个Calendar
实例,可能会导致不可预测的结果.Calendar
类中的月份是从0开始计数的,这种设计很容易导致错误.Calendar
类中的方法名不够直观,比如要设置月份要使用set(Calendar.MONTH, month)
,而不是setMonth(month)
.
DateFormat
类的缺点
DateFormat
类不是线程安全的,如果多个线程同时访问一个DateFormat实例,可能会导致不可预测的结果.DateFormat
类中的解析和格式化方法都很慢,因为它们需要进行字符串和日期之间的转换.
新的日期和时间API
java.time
包的类
1 | ├── Clock.java |
LocalDate
,LocalTime
1 | /** |
LocalDate
是一个不可变对象,它只提供简单的日期,并不包含当天的时间信息.此外它也不附带任何与时区相关的信息.LocalTime
是一个不可变对象,它只提供简单的时间,并不包含当天的日期信息.此外它也不附带任何与时区相关的信息.
1 |
|
LocalDateTime
LocalDateTime
是LocalDate
和LocalTime
的合并类,它同时表示了日期和时间,但不带有时区信息.
1 |
|
Instant
机器的日期和时间格式
- 基本上它是以Unix元年时间(传统的设定为UTC时区1970年1月1日午夜时分)开始所经历的秒数进行计算
1 |
|
Duration
和Period
时间间隔
-
Duration
类表示时间的持续时间,通常用于表示两个时间点之间的时间间隔.它可以精确地表示秒、纳秒和毫秒之间的时间间隔. -
Period
类表示时间的周期,通常用于表示两个日期之间的时间间隔,如年、月、日等.它可以精确地表示年、月、日之间的时间间隔.
1 |
|
操纵日期
- 使用
withAttribute
方法操作时间日期,withAttribute
方法会创建对象的一个副本,并按照需要修改它的属性. - 注意点: 使用
withAttribute
方法不会修改原来的对象.
1 |
|
方法名 | 是否是静态方法 | 描述 |
---|---|---|
from |
是 | 依据传入的 Temporal对象创建对象实例 |
now |
是 | 依据系统时钟创建 Temporal对象 |
of |
是 | 由 Temporal对象的某个部分创建该对象的实例 |
parse |
是 | 由字符串创建 Temporal对象的实例 |
atOffset |
否 | 将 Temporal对象和某个时区偏移相结合 |
atZone |
否 | 将 Temporal对象和某个时区相结合 |
format |
否 | 使用某个指定的格式器将 Temporal对象转换为字符串(Instant类不提供该方法) |
get |
否 | 读取 Temporal对象的某一部分的值 |
minus |
否 | 创建 Temporal对象的一个副本,通过将当前 Temporal对象的值减去一定的时长 创建该副本 |
plus |
否 | 创建 Temporal对象的一个副本,通过将当前 Temporal对象的值加上一定的时长 创建该副本 |
with |
否 | 以该 Temporal对象为模板,对某些状态进行修改创建该对象的副本 |
使用TemporalAdjusters
TemporalAdjuster
的作用是提供一种通用的、灵活的方式来调整日期时间对象,可以实现各种日期时间调整的需求,比如调整到下一个工作日、下个月的第一天、下一个星期六等等.
1 | import static java.time.temporal.TemporalAdjusters.*; |
方法名 | 描述 |
---|---|
dayOfWeekInMonth(int ordinal) |
返回指定月份中第几个星期几,例如第2个星期五. |
firstDayOfMonth() |
返回当前日期所在月份的第一天日期. |
firstDayOfNextMonth() |
返回当前日期所在月份的下一个月的第一天日期. |
firstDayOfNextYear() |
返回当前日期所在年份的下一年的第一天日期. |
firstDayOfYear() |
返回当前日期所在年份的第一天日期. |
firstInMonth(DayOfWeek dayOfWeek) |
返回当前日期所在月份中第一个指定星期几的日期. |
lastDayOfMonth() |
返回当前日期所在月份的最后一天日期. |
lastDayOfNextMonth() |
返回当前日期所在月份的下一个月的最后一天日期. |
lastDayOfNextYear() |
返回当前日期所在年份的下一年的最后一天日期. |
lastDayOfYear() |
返回当前日期所在年份的最后一天日期. |
lastInMonth(DayOfWeek dayOfWeek) |
返回当前日期所在月份中最后一个指定星期几的日期. |
next(DayOfWeek dayOfWeek) |
返回当前日期之后的第一个指定星期几的日期. |
previous(DayOfWeek dayOfWeek) |
返回当前日期之前的第一个指定星期几的日期. |
nextOrSame(DayOfWeek dayOfWeek) |
返回当前日期之后的第一个指定星期几的日期,如果当前日期已经是指定星期几,则返回当前日期. |
previousOrSame(DayOfWeek dayOfWeek) |
返回当前日期之前的第一个指定星期几的日期,如果当前日期已经是指定星期几,则返回当前日期. |
1 | @FunctionalInterface |
1 | // 自定义TemporalAdjuster |
DateTimeFormatter
格式化
1 |
|
ZoneId
处理不同时区
- 新的
java.time.ZoneId
类是老版java.util.TimeZone
的替代品
1 |
|
新老API转换
1 | /** |
1 | class TimeUtilTest { |
LocalDate -> LocalDateTime
1 | LocalDate localDate = LocalDate.parse("2019-01-04"); |
LocalDateTime -> LocalDate
1 | LocalDateTime localDateTime = LocalDateTime.now(); |
LocalDateTime -> Date
1 | // 获取当前 LocalDateTime |
Date -> LocalDateTime
1 | Date date = new Date(); |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 HoleLin's Blog!