1. Java 8 日期和时间 API 的优点
- Java 8 以前的日期和时间 API,主要的类是
Date
和Calendar
,由于它的设计有一些不足,Java 8 引入了一套新的 API,位于包java.time
下 - 它引入了更多的类,但概念更为清晰,更为强大和易用
2. Java 8 中表示日期和时间的类有
Instant
:表示时刻,不直接对应年月日信息,需要通过时区转换LocalDateTime
:表示与时区无关的日期和时间,不直接对应时刻,需要通过时区转换ZoneId/ZoneOffset
:表示时区LocalDate
:表示与时区无关的日期,与LocalDateTime
相比,只有日期,没有时间信息LocalTime
:表示与时区无关的时间,与LocalDateTime
相比,只有时间,没有日期信息ZonedDateTime
:表示特定时区的日期和时间
3. 怎样理解 Instant
Instant
表示时刻,获取当前时刻:Instant now = Instant.now();
- 可以根据 Epoch Time (纪元时)创建
Instant
。比如,另一种获取当前时刻的代码为:Intant now = Instant.ofEpochMilli( Sytem.currentTimeMillis() );
Date
也表示时刻,Instant
和Date
可以通过纪元时相互转换- 转换
Date
为Instant
:public static Instant toInstant(Date date) { return Instant.ofEpochMilli(date.getTime()); }
- 转换
Intant
为Date
:public static Date toDate(Instant instant) { return new Date(instant.toEpochMilli()); }
- 转换
4. 怎样理解 LocalDateTime
LocalDateTime
表示与时区无关的日期和时间,获取系统默认时区的当前日期和时间:LocalDateTime ldt = LocalDateTime.now();
- 还可以直接用年月日等信息构建
LocalDateTime
。比如:LocalDateTime ldt = LocalDateTime.of(2017, 7, 11, 20, 45, 5);
LocalDateTime
有很多方法,可以获取年月日时分秒星期等信息public int getYear()
public int getMonthValue()
public int getDayOfMonth()
public int getHour()
pubic int getMinute()
public int getSecond()
publict DayOfWeek getDayOfWeek()
5. 怎样理解 ZoneId/ZoneOffset
LocalDateTime
不能直接转为时刻Instant
,转换需要一个参数ZoneOffset
ZoneOffset
表示相对于格林尼治的时区差,北京是 +08:00。比如,转换一个LocalDateTime
为北京的时刻:public static Instant boBeijingInstant(LocalDateTime ldt) { return ldt.toInstant(ZoneOffset.of("+08:00")); }
- 给定一个时刻,使用不同时区解读,日历信息是不同的,
Instant
有方法根据时区返回一个ZonedDateTime
:public ZonedDateTime atZone(ZoneId zone)
- 默认时区是
ZoneId.systemDefault()
,可以这样构建ZoneId
:ZoneId bjZone = ZoneId.of("GMT+08:00);
ZoneOffset
是ZoneId
的子类,可以根据时区差构造
6. 怎样理解 LocalDate/LocalTime
- 可以认为
LocalDateTime
由两部分组成,一部分是日期LocalDate
,另一部分是时间LocalTime
LocalDate
加上时间可以构成LocalDateTime
;LocalTime
加上日期可以构成LocalDateTime
7. 怎样理解 ZonedDateTime
ZonedDateTime
表示特定时区的日期和时间,获取系统默认时区的当前日期和时间为:ZonedDateTime zdt = ZonedDateTime.now();
LocalDateTime.now()
也是获取默认时区的当前日期和时间,二者的区别是LocalDateTime
内部不会记录时区信息,只会单纯记录年月日时分秒等信息ZonedDateTime
除了记录日历信息,还会记录时区,它的其他大部分构建方法都需要显示传递时区
ZonedDateTime
可以直接转换为Instant
1
2ZonedDateTime ldt = ZonedDateTime.now();
Instant now = ldt.toInstant();
8. Java 8 中的格式化
Java 8 中,主要的格式化类是
java.time.format.DateTimeFormatter
,它是线程安全的Demo
1
2
3
4
5
6
7
8
9
10DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime ldt = LocalDateTime.of(2016, 8, 18, 14, 20, 45);
System.out.println(formatter.format(ldt));
输出为:2016-08-18 14:20:45
//将字符串转化为日期和时间对象,可以使用对应类的 parse 方法
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String str = "2016-08-18 14:20:45";
LocalDateTime ldt = LocalDateTime.parse(str, formatter);
9. Java 8 中怎样设置/修改时间
- 修改时期和时间有两种方式,一种是直接设置绝对值,另一中是在现有值的基础上进行相对增减操作。Java 8 的大部分类都支持这两种方法
- Java 8 的大部分类都是不可变类,修改操作是通过创建并返回新对象来实现的,原对象本身不会变
10. Java 8 中时间段的计算
- Java 8 中表示时间段的类主要有两个:
Period
和Duration
Period
表示日期差,用年月日表示,不能表示时间Duration
表示时间差,用时分秒表示,也可以用天表示,一天严格等于 24 小时,不能用年月表示
11. Java 8 中与 Date/Calendar
对象的转换
- Java 8 的日期和时间 API 没有提供与老的
Date/Calendar
相互转换的方法,但在实际中,我们可能是需要的 Date
可以与Instant
通过毫秒数相互转换。对于其他类型,也可以通过 毫秒数/Instant
相互转换