前言
Java8 引入了新的 Date-Time API(JSR 310)来改进时间、日期的处理。时间和日期的管理一直是最令 Java 开发者痛苦的问题。java.util.Date 和后来的 java.util.Calendar 一直没有解决这个问题(甚至令开发者更加迷茫)。
因为上面这些原因,诞生了第三方库 Joda-Time,可以替代 Java 的时间管理 API。Java8 中新的时间和日期管理 API 深受 Joda-Time 影响,并吸收了很多 Joda-Time 的精华。新的 java.time 包包含了所有关于瞬时时间(Instant),持续时间(Duration),日期(Date),时间(Time),时区(Time-Zone)以及时间段(Period)操作的类。新设计的 API 认真考虑了这些类的不变性(从 java.util.Calendar 吸取的教训),如果某个实例需要修改,则返回一个新的对象。
- ZoneId: 时区 ID,用来确定 Instant 和 LocalDateTime 互相转换的规则
- Instant: 用来表示时间线上的一个点
- LocalDate: 表示没有时区的日期,LocalDate 是不可变并且线程安全的
- LocalTime: 表示没有时区的时间,LocalTime 是不可变并且线程安全的
- LocalDateTime: 表示没有时区的日期时间,LocalDateTime 是不可变并且线程安全的
- Clock: 用于访问当前时刻、日期、时间,用到时区
- Duration: 用秒和纳秒表示时间的数量
最常用的就是 LocalDate、LocalTime、LocalDateTime 了,从它们的名字就可以看出是操作日期和时间的。
LocalDate
LocalDate 是一个不可变的类,它表示默认格式 (yyyy-MM-dd) 的日期,我们可以使用 now()方法得到当前时间,也可以提供输入年份、月份和日期的输入参数来创建一个 LocalDate 实例。该类为 now()方法提供了重载方法,我们可以传入 ZoneId 来获得指定时区的日期。
- 在 Java8 中如何获取当天的日期?
1 | LocalDate localDate = LocalDate.now(); |
- 在 Java8 中如何获取当前的年月日?
1 | LocalDate today = LocalDate.parse("2017-12-07"); |
- 在 Java8 中如何获取某个特定的日期?
1 | // 1. 根据年月日取日期 |
- 在 Java8 中如何检查两个日期是否相等?
1 | LocalDate today = LocalDate.parse("2017-12-07"); |
- 在 Java8 中如何检查重复事件,比如说生日?
1 | LocalDate today = LocalDate.parse("2017-12-07"); |
- 在 Java8 中如何获取 1 周后的日期?
1 | LocalDate today = LocalDate.parse("2017-12-12"); |
- 在 Java8 中如何获取一年前后的日期?
1 | LocalDate today = LocalDate.parse("2017-12-12"); |
- 在 Java8 中如何检查闰年?
1 | LocalDate today = LocalDate.now(); |
- 在 Java8 中如何获取这个月的第一天?
1 | LocalDate today = LocalDate.parse("2017-12-12"); |
- 在 Java8 中如何判断某个日期是在另一个日期的前面还是后面?
1 | LocalDate today = LocalDate.parse("2017-12-12"); |
LocalTime
LocalTime 是一个不可变的类,它的实例代表一个符合人类可读格式的时间,默认格式是 hh:mm:ss.zzz。像 LocalDate 一样,该类也提供了时区支持,同时也可以传入小时、分钟和秒等输入参数创建实例。
- 在 Java8 中如何获取当天的时间?
1 | // 1.Current Time |
- 在 Java8 中如何获取当前的小时、分钟?
1 | LocalTime nowTime = LocalTime.parse("15:02:53"); |
- 在 Java8 中如何获取某个特定的时间?
1 | // 1.Creating LocalTime by providing input arguments |
LocalDateTime
LocalDateTime 是一个不可变的日期 - 时间对象,它表示一组日期 - 时间,默认格式是 yyyy-MM-ddTHH-mm-ss.zzz。它提供了一个工厂方法,通过接收 LocalDate 和 LocalTime 输入参数,来创建 LocalDateTime 实例。
- 在 Java8 中如何获取当天的日期时间?
1 | // 1.Current Date |
Instant
Instant 类是用在机器可读的时间格式上的,它以 Unix 时间戳 < sup>[1] 的形式存储日期时间。java.time.Instant 类在时间线上模拟单个瞬时点。Instant 对象包含两个值:秒数和纳秒数。其中秒数指的是 epoch 时间戳,而纳秒数指的是该秒内的纳秒时间。
- 在 Java8 中如何获取当前的时间戳?
1 | // 1.Current timestamp[Instant.now()使用等是 UTC 时间 Clock.systemUTC().instant(), 输出 2017-12-12T08:48:16.253Z 和北京时间相差 8 个时区] |
- 在 Java8 中如何获取从 1970 年 1 月 1 日到现在的毫秒?
1 | // 1. 将此瞬间转换为 1970-01-01T00:00:00Z 时代的毫秒数。 |
- 在 Java8 中如何获取两个时间的时间差?
1 | Instant instant1 = Instant.now(); |
Duration
java.time.Duration 类以秒和纳秒为单位模拟一个数量或时间量。可以使用其他基于持续时间的单位访问它,例如分钟和小时。Duration 表示以秒为单位的时长,精确到纳秒。
- 在 Java8 中如何获取持续时间?
1 | // 表示十九小时二十六分钟三十二点二六八秒 |
- 在 Java8 中如何获取两个时间的持续时间?
1 | Duration duration1 = Duration.between(Instant.EPOCH, Instant.now()); |
Period
java.time.Period 类根据年,月和日来模拟一个数量或时间量。Period 表示以天为单位的时长,精确到天。
- 在 Java8 中如何获取时间段?
1 | // 表示一年两个月零三天 |
- 在 Java8 中如何获取两个日期的时间段?
1 | LocalDate today = LocalDate.parse("2017-02-23"); |
- 在 Java8 中如何具体计算两个时间点之间的秒数或天数?
1 | // 离那个什么中华民族的伟大复兴还有多少天 |
DateTimerFormatter
将一个日期格式转换为不同的格式,之后再解析一个字符串,得到日期时间对象。
- 在 Java8 中如何使用预定义的格式器来对日期进行解析 / 格式化?
1 | String dayAfterTommorrow = "20171216"; |
- 在 Java8 中如何使用自定义的格式器来解析日期?
1 | String goodFriday = "十月 18 2014"; |
- 在 Java8 中如何对日期进行格式化,转换成字符串?
1 | // Format examples |
旧的日期时间支持
旧的日期 / 时间类已经在几乎所有的应用程序中使用,因此做到向下兼容是必须的。这也是为什么会有若干工具方法帮助我们将旧的类转换为新的类,反之亦然。
1.Date 和 Instant 互相转换
1 | // Instant to Date |
2.Date 和 LocalDateTime 相互转换
1 | // Date to LocalDateTime |
3.Date 和 LocalDate 相互转换
1 | // LocalDate to Date[LocalDate -> LocalDateTime -> Date] |
注脚
[1].Unix 时间戳: unix 时间戳是从格林威治时间 1970 年 1 月 1 日(UTC/GMT 的午夜)开始所经过的秒数,不考虑闰秒。
Java8 那些事儿系列
- Java8 那些事儿(一):Stream 函数式编程
- Java8 那些事儿(二):Optional 类解决空指针异常
- Java8 那些事儿(三):Date/Time API(JSR 310)
- Java8 那些事儿(四):增强的 Map 集合
- Java8 那些事儿(五):函数式接口
- Java8 那些事儿(六):从 CompletableFuture 到异步编程