# 3. JDK 8 中新日期时间 API
# 3.1 JDK8 新引入的关于日期的包
java.time – 包含值对象的基础包
java.time.chrono – 提供对不同的日历系统的访问
java.time.format – 格式化和解析时间和日期
java.time.temporal – 包括底层框架和扩展特性
java.time.zone – 包含时区支持的类
# 3.2 五个重要的类
本地日期 LocalDate
- 代表IOS格式(yyyy-MM-dd)的日期,可以存储 生日、纪念日等日期。
本地时间 LocalTime
- 表示一个时间,而不是日期。
本地日期时间 LocalDateTime
- 用来表示日期和时间的,这是一个最常用的类之一。
时区 ZonedDateTime
持续时间 Duration
LocalDate、LocalTime、LocalDateTime 类是其中较重要的几个类,它们的实例 是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。 它们提供了简单的本地日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。
# 3.3 常用方法
# 3.4 示例
# 3.4.1 获取当前日期/时间
LocalDate localDate = LocalDate.now();
System.out.println(localDate); //2020-10-19
LocalTime localTime = LocalTime.now();
System.out.println(localTime); //15:02:25.574
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime); //2020-10-19T15:02:55.039
LocalDateTime of1 = LocalDateTime.of(localDate, localTime);
System.out.println(of1); //2020-10-19T15:07:58.364
LocalDateTime of2 = LocalDateTime.of(2010,11,11,11,1,11);
System.out.println(of2); //2010-11-11T11:01:11
# 3.4.2 获取
LocalDate localDate = LocalDate.now();
int dayOfMonth = localDate.getDayOfMonth();
System.out.println("dayOfMonth: " + dayOfMonth); //dayOfMonth: 19
DayOfWeek dayOfWeek = localDate.getDayOfWeek();
System.out.println("dayOfWeek: " + dayOfWeek.getValue()); //dayOfWeek: 1
int dayOfYear = localDate.getDayOfYear();
System.out.println("dayOfYear: " + dayOfYear); //dayOfYear: 293
int monthValue = localDate.getMonthValue();
System.out.println("monthValue: " + monthValue); //monthValue: 10
LocalTime localTime = LocalTime.now();
int hour = localTime.getHour();
System.out.println("hour: " + hour); //hour: 15
int minute = localTime.getMinute();
System.out.println("minute: " + minute); //minute: 8
int second = localTime.getSecond();
System.out.println("second: " + second); //second: 24
# 3.4.3 修改
LocalDate localDate = LocalDate.now();
LocalDate localDate1 = localDate.plusDays(40);
LocalDate localDate2 = localDate.plusWeeks(3);
LocalDate localDate3 = localDate.plusMonths(13);
LocalDate localDate4 = localDate.plusYears(3);
System.out.println("localDate: " + localDate); //localDate: 2020-10-19 => 不可变性
System.out.println("localDate1: " + localDate1); //localDate1: 2020-11-28
System.out.println("localDate2: " + localDate2); //localDate2: 2020-11-09
System.out.println("localDate3: " + localDate3); //localDate3: 2021-11-19
System.out.println("localDate4: " + localDate4); //localDate4: 2023-10-19
LocalTime localTime = LocalTime.now();
LocalTime localTime1 = localTime.plusHours(25);
LocalTime localTime2 = localTime.plusMinutes(70);
LocalTime localTime3 = localTime.plusSeconds(100);
System.out.println("localTime: " + localTime); //localTime: 15:16:15.487 => 不可变性
System.out.println("localTime1: " + localTime1); //localTime1: 16:16:15.487
System.out.println("localTime2: " + localTime2); //localTime2: 16:26:15.487
System.out.println("localTime3: " + localTime3); //localTime3: 15:17:55.487
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime localDateTime1 = localDateTime.minusYears(10);
LocalDateTime localDateTime2 = localDateTime.minusMonths(13);
LocalDateTime localDateTime3 = localDateTime.minusDays(400);
LocalDateTime localDateTime4 = localDateTime.minusHours(73);
LocalDateTime localDateTime5 = localDateTime.minusMinutes(100);
LocalDateTime localDateTime6 = localDateTime.minusSeconds(1024);
System.out.println("localDateTime: " + localDateTime); //localDateTime: 2020-10-19T15:16:15.487 => 不可变
System.out.println("localDateTime1: " + localDateTime1); //localDateTime1: 2010-10-19T15:16:15.487
System.out.println("localDateTime2: " + localDateTime2); //localDateTime2: 2019-09-19T15:16:15.487
System.out.println("localDateTime3: " + localDateTime3); //localDateTime3: 2019-09-15T15:16:15.487
System.out.println("localDateTime4: " + localDateTime4); //localDateTime4: 2020-10-16T14:16:15.487
System.out.println("localDateTime5: " + localDateTime5); //localDateTime5: 2020-10-19T13:36:15.487
System.out.println("localDateTime6: " + localDateTime6); //localDateTime6: 2020-10-19T14:59:11.487
# 3.5 瞬时 Instant
Instant:时间线上的一个瞬时点。 这可能被用来记录应用程序中的事件时间戳。
时间戳是指(北京时间1970年01月01 日08时00分00秒)起至现在的总秒数。
/**
* now()
* 当前的格林威治时间。(北京时间-8h)
*/
Instant now = Instant.now();
System.out.println(now); //2020-10-19T07:29:17.916Z
/**
* now(temporalAccessor)
* 从格林威治时间1970年01月01日00时00分00秒延后多少秒
*/
TemporalAccessor temporalAccessor = new TemporalAccessor() {
//是否可用,为 true 的时候才可以当参数传到 now() 里面,否则报错
@Override
public boolean isSupported(TemporalField field) {
return true;
}
//从格林威治时间1970年01月01日00时00分00秒延后多少秒
@Override
public long getLong(TemporalField field) {
return 360;
}
};
Instant from = Instant.from(temporalAccessor);
System.out.println(from); //1970-01-01T00:06:00.000000360Z
/**
* ofEpochMilli(Long epochMilli)
* 从格林威治时间1970年01月01日00时00分00秒延后多少豪秒
*/
Instant instantMilli = Instant.ofEpochMilli(1000);
System.out.println(instantMilli); //1970-01-01T00:00:01Z
/**
* ofEpochSecond(Long second)
* 从格林威治时间1970年01月01日00时00分00秒延后多少秒
*/
Instant instantSecond = Instant.ofEpochSecond(60);
System.out.println(instantSecond); //1970-01-01T00:01:00Z
/**
* atOffset(zoneOffset)
* 结合即时的偏移来创建一个 OffsetDateTime,这样就可以获取北京时间了
*/
ZoneOffset zoneOffset = ZoneOffset.ofHours(8);
OffsetDateTime bjNow = now.atOffset(zoneOffset);
System.out.println(bjNow); //2020-10-19T15:45:27.328+08:00
/**
* toEpochMilli()
* 返回从格林威治时间1970年01月01日00时00分00秒到当前instant对象的毫秒数,即时间戳
*/
long epochMilli = instantSecond.toEpochMilli();
System.out.println(epochMilli); //60000
# 3.6 格式化&解析
java.time.format.DateTimeFormatter
提供了 3 种格式化方法:
# 3.6.1 预定义的标准格式
# ISO_LOCAL_DATE_TIME
只支持 LocalDateTime :
DateTimeFormatter isoLocalDateTime = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
//格式化
LocalDateTime now = LocalDateTime.now();
String nowLocalDateTimeFormat = isoLocalDateTime.format(now);
System.out.println("前:"+now); //前: 2020-10-19T16:00:42.823
System.out.println("后:"+nowLocalDateTimeFormat); //后: 2020-10-19T16:00:42.823
//解析
TemporalAccessor parse = isoLocalDateTime.parse("2020-10-19T16:00:42.823");
System.out.println(parse); //{},ISO resolved to 2020-10-19T16:00:42.823
# ISO_LOCAL_DATE
只支持 LocalDateTime 和 LocalDate:
DateTimeFormatter isoLocalDate = DateTimeFormatter.ISO_LOCAL_DATE;
//格式化
LocalDateTime nowLocalDateTime = LocalDateTime.now();
String formatLocalDateTime = isoLocalDate.format(nowLocalDateTime);
System.out.println(formatLocalDateTime); //2020-10-19
LocalDate nowLocalDate = LocalDate.now();
String formatLocalDate = isoLocalDate.format(nowLocalDate);
System.out.println(formatLocalDate); //2020-10-19
//解析
TemporalAccessor parse1 = isoLocalDate.parse("2020-10-19");
System.out.println(parse1); //{},ISO resolved to 2020-10-19
# ISO_LOCAL_TIME
只支持 LocalDateTime 和 LocalTime:
DateTimeFormatter isoLocalTime = DateTimeFormatter.ISO_LOCAL_TIME;
//格式化
LocalDateTime localDateTime = LocalDateTime.now();
String formatLocalDateTime = isoLocalTime.format(localDateTime);
System.out.println(formatLocalDateTime); //16:13:27.993
LocalTime localTime = LocalTime.now();
String formatLocalTime = isoLocalTime.format(localTime);
System.out.println(formatLocalTime); //16:14:27.796
//解析
TemporalAccessor parse = isoLocalTime.parse("16:13:27.993");
System.out.println(parse); //{},ISO resolved to 16:13:27.993
# 3.6.2 本地化相关的格式
# ofLocalizedDateTime()
LONG/MEDIUM/SHORT,适用于 LocalDateTime
//LONG
DateTimeFormatter dateTimeFormatterLong = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
LocalDateTime now = LocalDateTime.now();
String format = dateTimeFormatterLong.format(now);
System.out.println(format); //2020年10月19日 下午04时16分52秒
//MEDIUM
DateTimeFormatter dateTimeFormatterMedium = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);
format = dateTimeFormatterMedium.format(now);
System.out.println(format); //2020-10-19 16:18:05
//SHORT
DateTimeFormatter dateTimeFormatterShort = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
format = dateTimeFormatterShort.format(now);
System.out.println(format); //20-10-19 下午4:18
# ofLocalizedDate()
FULL/LONG/MEDIUM/SHORT,适用于 LocalDate
和 LocalDateTime
//FULL
DateTimeFormatter dateTimeFormatterFull = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
LocalDate now = LocalDate.now();
String format = dateTimeFormatterFull.format(now);
System.out.println(format); //2020年10月19日 星期一
//LONG
DateTimeFormatter dateTimeFormatterLong = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG);
format = dateTimeFormatterLong.format(now);
System.out.println(format); //2020年10月19日
//MEDIUM
DateTimeFormatter dateTimeFormatterMedium = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
format = dateTimeFormatterMedium.format(now);
System.out.println(format); //2020-10-19
//SHORT
DateTimeFormatter dateTimeFormatterShort = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
format = dateTimeFormatterShort.format(now);
System.out.println(format); //20-10-19
# 3.6.3 自定义的格式
# ofPattern(String pattern)
//小时用大写H,则用24小时计时
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String format = dtf.format(LocalDateTime.now());
System.out.println(format); //2020-10-19 16:29:04
//小时用小写h,则用12小时计时
DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
format = dtf2.format(LocalDateTime.now());
System.out.println(format); //2020-10-19 04:29:29
# 3.7 其他 API
ZoneId
该类中包含了所有的时区信息,一个时区的ID,如 Europe/Paris。
ZonedDateTime
一个在ISO-8601日历系统时区的日期时间,如 2007-12-03T10:15:30+01:00 Europe/Paris。
其中每一个市区都对应一个ID,地区ID都为“{区域/城市}”,例如:Asia/Shanghai
Clock
使用时区提供对当前即时、日期和时间的访问的时钟。
Duration
持续时间。用于计算两个“时间”间隔。
Period
日期间隔。用于计算两个“日期”间隔
TemporalAdjuster
时间校正器。有时我们可能需要获取例如:将日期调整到“下一个工作日”等操作。
TemporalAdjusters
该类通过静态方法 (firstDayOfXxx()/lastDayOfXxx()/nextXxx())提供了大量的常用 TemporalAdjuster 的实现。