・所有的java.time对象都是不可变的
・一个瞬间(Instant)是时间线上的一个点
・在Java事件中,每天都是86400秒
・持续时间(Duration)是两个瞬间之间的时间
・LocalXXX 没有时区信息
・TemporalAdjuster可以处理常用日历计算美丽如找到某个月的第一个星期二
1.时间线
Instant对象为时间轴上的一个点,原点为1970.1.1日午夜
Duration表示两个瞬时点之间的时间量。
两者提供多个plus/minus/multipliedBy/dividedBy方法以供计算
也可以使用toNano方法以long值进行计算
保存Api链接随时查阅:
Instant https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html
Duration https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html
2.本地日期
在新的Java API中,包含两种人类时间:本地日期/带时区的日期
由于有些操作不需要时区,或者为了排除夏令时等的影响,使用本地日期进行计算更为适合
LocalDate包含年月日的信息:
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1991,2,3);
LocalDate birthday = LocalDate.of(1991, Month.JUNE, 14);
LocalDate:https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html
两个Instant之间的距离是Duration,对于本地日期,两个LocalDate之间的距离就是Period(时段)
Period: https://docs.oracle.com/javase/8/docs/api/java/time/Period.html
例如增加一年的时间,如果使用day.plus(Duration.ofDays(365))在闰年的时候便会错误,正确的方法是birthday.plusYear(1)或者birthday.plus(Period.ofYear(1))
注意:LocalDate的getDayOfWeek与Calendar不同,周一为1,周日为7(Calendar周日为1,周六为7)
3.日期校正器
TemporalAdjuster提供许多静态方法进行常用校正。
例如将校正方法的结果传递给LocalDate的with方法,计算某个月的第一个周二
LocalDate.of(year, month, 1).with(TemporalAdjuster.nextOrSame(DayOfWeek.TUESDAY));
也可以实现TemporalAdjuster接口创建自己的校正
TemporalAdjuster NEXT_WORKDAY =TemporalAdjusters.ofDateAdjuster(w -> {
LocalDate = result =w;
// 计算日期..
return result;
});
TemporalAdjuster: https://docs.oracle.com/javase/jp/8/docs/api/java/time/temporal/TemporalAdjusters.html
4.本地时间
与本地日期相对,LocalTime表示一天中某个时间。LocalDateTime表示一个日期和时间
LocalTime.now()
LocalTime.of(22,30)
LocalTime.of(22,30, 10);
LocalTime: https://docs.oracle.com/javase/8/docs/api/java/time/LocalTime.html
LocalDateTime:https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html
5.带时区的时间
每个时区都有一个ID,比如America/New_York。想要获得所有时区可以调用ZoneId.getAvailableIds
根据指定的id,ZoneId.of(id)会返回一个ZoneId对象
根据ZoneId,可以调用LocalDateTime的atZone(ZoneId)方法,获取一个ZonedDateTime对象
或者调用静态方法ZoneDateTime.of(year, month, day, hour, minute, second, nano, zoneId)
ZonedDateTime代表一个特定的时间点,可以调用toInstant获得一个Instant对象
反过来,instant.atZone(ZoneId.of("UTC"))可以获得格林威治皇家天文台为标准的ZonedDateTime对象
ZonedDateTime与LocalDateTime许多方法都一样,只是夏令时带来了一些复杂性
ZonedDateTime: https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html
6.格式化和解析
DateTimeFormatter用以代替java.util.Dateformat,如果需要转换,可以使用formatter.toFormat()
DateTimeFormatter类提供三种格式化方法:
1. 预定义标准格式
DateTimeFormatter.ISO_DATE_TIME.format(datetime);
详见下表:
Formatter | Description | Example |
---|---|---|
BASIC_ISO_DATE |
Basic ISO date | '20111203' |
ISO_LOCAL_DATE |
ISO Local Date | '2011-12-03' |
ISO_OFFSET_DATE |
ISO Date with offset | '2011-12-03+01:00' |
ISO_DATE |
ISO Date with or without offset | '2011-12-03+01:00'; '2011-12-03' |
ISO_LOCAL_TIME |
Time without offset | '10:15:30' |
ISO_OFFSET_TIME |
Time with offset | '10:15:30+01:00' |
ISO_TIME |
Time with or without offset | '10:15:30+01:00'; '10:15:30' |
ISO_LOCAL_DATE_TIME |
ISO Local Date and Time | '2011-12-03T10:15:30' |
ISO_OFFSET_DATE_TIME |
Date Time with Offset | 2011-12-03T10:15:30+01:00' |
ISO_ZONED_DATE_TIME |
Zoned Date Time | '2011-12-03T10:15:30+01:00[Europe/Paris]' |
ISO_DATE_TIME |
Date and time with ZoneId | '2011-12-03T10:15:30+01:00[Europe/Paris]' |
ISO_ORDINAL_DATE |
Year and day of year | '2012-337' |
ISO_WEEK_DATE |
Year and Week | 2012-W48-6' |
ISO_INSTANT |
Date and Time of an Instant | '2011-12-03T10:15:30Z' |
RFC_1123_DATE_TIME |
RFC 1123 / RFC 822 | 'Tue, 3 Jun 2008 11:05:30 GMT' |
2. 语言环境相关格式
Formatter | Description | Example |
---|---|---|
ofLocalizedDate(dateStyle) |
Formatter with date style from the locale | '2011-12-03' |
ofLocalizedTime(timeStyle) |
Formatter with time style from the locale | '10:15:30' |
ofLocalizedDateTime(dateTimeStyle) |
Formatter with a style for date and time from the locale | '3 Jun 2008 11:05:30' |
ofLocalizedDateTime(dateStyle,timeStyle) |
Formatter with date and time styles from the locale | '3 Jun 2008 11:05' |
Enum Constant and Description |
---|
FULL
Full text style, with the most detail.
|
LONG
Long text style, with lots of detail.
|
MEDIUM
Medium text style, with some detail.
|
SHORT
Short text style, typically numeric.
|
这些方法使用默认的语言环境,可以通过withLocal方法设定语言环境
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.Long).withLocal(Locale.FRENCH).format(datetime);
3. 指定模式
DateTimeFormatter.ofPattern("E yyyy-MM-dd HH:mm")
常用格式化符号:
All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters. The following pattern letters are defined:
Symbol Meaning Presentation Examples ------ ------- ------------ ------- G era text AD; Anno Domini; A u year year 2004; 04 y year-of-era year 2004; 04 D day-of-year number 189 M/L month-of-year number/text 7; 07; Jul; July; J d day-of-month number 10 Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter Y week-based-year year 1996; 96 w week-of-week-based-year number 27 W week-of-month number 4 E day-of-week text Tue; Tuesday; T e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T F week-of-month number 3 a am-pm-of-day text PM h clock-hour-of-am-pm (1-12) number 12 K hour-of-am-pm (0-11) number 0 k clock-hour-of-am-pm (1-24) number 0 H hour-of-day (0-23) number 0 m minute-of-hour number 30 s second-of-minute number 55 S fraction-of-second fraction 978 A milli-of-day number 1234 n nano-of-second number 987654321 N nano-of-day number 1234000000 V time-zone ID zone-id America/Los_Angeles; Z; -08:30 z time-zone name zone-name Pacific Standard Time; PST O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00; X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15; x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15; Z zone-offset offset-Z +0000; -0800; -08:00; p pad next pad modifier 1 ' escape for text delimiter '' single quote literal ' [ optional section start ] optional section end # reserved for future use { reserved for future use } reserved for future use
DateTimeFormatter:https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());