# 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 常用方法

image-20201019145848151

# 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秒)起至现在的总秒数。

image-20201019152437594
/**
 * 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,适用于 LocalDateLocalDateTime

//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 的实现。

# 3.8 与传统日期处理的转换

image-20201019155407269

上次更新: 8/27/2021, 5:57:47 PM