Java8新特性 | 新的日期时间API

本文源码:Gitee·点这里

Java 8通过发布新的JSR 310: Date and Time API来进一步加强对日期与时间的处理。java.time是基于国际化标准日历系统(International Organization for Standardization)ISO-8601的,同时java.time.chrono支持对全球日历系统的扩展。

新的java.time涵盖了所有处理日期、时间、日期-时间、时区、时刻(instants)、时长(during)与时钟(clock)的操作。所有的类都是不可变的,线程安全的。

该套API的方法,通过使用一致的方法前缀来管理:

  • of - 静态工厂方法,用于根据属性值创建实例
  • parse - 静态工厂方法集中于解析
  • get - 获取get的值
  • is - 检查是否正确
  • with - 设定某个属性的值,不改变原实例值,而是创建一个新的实例
  • plus - 向对象添加值
  • minus - 从对象中减去值
  • to - 将此对象转换为另一种类型
  • at - 将此对象与另一个对象组合,如date.atTime(time)

LocalDate (日期)

LocalDate是一个不可变的日期对象,通常被视为年月日。 也可以访问其他日期字段,例如日期和星期。

该类是对日期的描述,不能代表时间线上的某一时刻,而且没有时间、偏移和时区。该类比较适合用于生日。通过下面的示例代码来了解其方法的使用。

示例代码:

public class LocalDateDemo {

    public static void main(String[] args) {
        // 从默认时区的系统时钟获取当前日期
        LocalDate localDate1 = LocalDate.now();
        // 将此日期输出为 String ,如 2007-12-03 。
        System.out.println("01: " + localDate1);

        // 从一年,一个月和一天获得一个 LocalDate的实例
        LocalDate localDate2 = LocalDate.of(2020, 12, 1);
        System.out.println("02: " + localDate2);

        // 从一年中的第n天获取LocalDate实例
        LocalDate localDate3 = LocalDate.ofYearDay(2020, 45);
        System.out.println("03: " + localDate3);

        // 从一个文本字符串(如 2007-12-03)获取一个 LocalDate的实例,使用默认 DateTimeFormatter.ISO_LOCAL_DATE 格式
        LocalDate localDate4 = LocalDate.parse("2020-12-02");
        System.out.println("04: " + localDate4);
        // 使用特定格式化,从文本字符串获取 LocalDate的实例。
        LocalDate localDate5 = LocalDate.parse("2020/10/03", DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        System.out.println("05: " + localDate5);

        // 获取年
        System.out.println("06: " + localDate5.getYear());
        // 获取月
        System.out.println("07: " + localDate5.getMonthValue());
        // 获取日
        System.out.println("08: " + localDate5.getDayOfMonth());

        // 是否在指定日期之后
        System.out.println("09: " + localDate5.isAfter(localDate4));
        // 是否在指定日期之前
        System.out.println("10: " + localDate5.isBefore(localDate4));
        // 是否与指定日期相等
        System.out.println("11: " + localDate5.isEqual(localDate4));

        // 更改年份,并返回新的实例
        System.out.println("12: " + localDate5.withYear(2019));
        // 更改月份,并返回新的实例
        System.out.println("13: " + localDate5.withMonth(10));
        // 更改日期,并返回新的实例
        System.out.println("14: " + localDate5.withDayOfMonth(9));

        // 年份增加指定值,并返回新的实例
        System.out.println("15: " + localDate5.plusYears(1));
        // 月份增加指定值,并返回新的实例
        System.out.println("16: " + localDate5.plusMonths(1));
        // 日期增加指定值,并返回新的实例
        System.out.println("17: " + localDate5.plusDays(1));

        // 年份减去指定值,并返回新的实例
        System.out.println("18: " + localDate5.minusYears(1));
        // 月份减去指定值,并返回新的实例
        System.out.println("19: " + localDate5.minusMonths(1));
        // 日期减去指定值,并返回新的实例
        System.out.println("20: " + localDate5.minusDays(1));

        // 按照指定格式返回一个字符串
        System.out.println("21: " + localDate5.format(DateTimeFormatter.ofPattern("yyyy/MM/dd")));

        // 添加时间的小时、分钟、秒,获取一个 LocalDateTime 实例
        System.out.println("22: " + localDate5.atTime(10, 11, 12));
        // 添加一个 LocalTime 获取一个 LocalDateTime 实例
        System.out.println("23: " + localDate5.atTime(LocalTime.now()));
    }
}

输出结果:

01: 2020-11-11
02: 2020-12-01
03: 2020-02-14
04: 2020-12-02
05: 2020-10-03
06: 2020
07: 10
08: 3
09: false
10: true
11: false
12: 2019-10-03
13: 2020-10-03
14: 2020-10-09
15: 2021-10-03
16: 2020-11-03
17: 2020-10-04
18: 2019-10-03
19: 2020-09-03
20: 2020-10-02
21: 2020/10/03
22: 2020-10-03T10:11:12
23: 2020-10-03T10:05:39.715

LocalTime (时间)

LocalTime是一个不可变的时间对象,通常被看作时-分-秒,精度为纳秒,例如:13:45:30.123456789。

它不存储日期、时区、偏移,也不能表示时间线上的某一时刻。通过下面的示例代码来了解其方法的使用。

示例代码:

public class LocalTimeDemo {

    public static void main(String[] args) {

        // 从默认时区的系统时钟获取当前时间
        LocalTime localTime1 = LocalTime.now();
        System.out.println("01: " + localTime1);

        // 通过时、分、秒创建一个 LocalTime 实例
        LocalTime localTime2 = LocalTime.of(10, 2, 15);
        System.out.println("02: " + localTime2);

        // 从一天中的第n秒获取 LocalTime 实例
        LocalTime localTime3 = LocalTime.ofSecondOfDay(100);
        System.out.println("03: " + localTime3);

        // 从一个文本字符串(如:10:15)获取一个 LocalTime 的实例,使用默认 DateTimeFormatter.ISO_LOCAL_TIME 格式
        LocalTime localTime4 = LocalTime.parse("10:01:12");
        System.out.println("04: " + localTime4);
        // 使用特定格式化,从文本字符串获取 LocalTime 的实例。
        LocalTime localTime5 = LocalTime.parse("11:02:13.111", DateTimeFormatter.ofPattern("HH:mm:ss.SSS"));
        System.out.println("05: " + localTime5);

        // 获取小时
        System.out.println("06: " + localTime5.getHour());
        // 获取分钟
        System.out.println("07: " + localTime5.getMinute());
        // 获取秒
        System.out.println("08: " + localTime5.getSecond());

        // 是否在指定时间之后
        System.out.println("09: " + localTime5.isAfter(localTime4));
        // 是否在指定时间之前
        System.out.println("10: " + localTime5.isBefore(localTime4));
        // 是否与指定时间相等
        System.out.println("11: " + localTime5.equals(localTime4));

        // 更改小时,并返回新的实例
        System.out.println("12: " + localTime5.withHour(12));
        // 更改分钟,并返回新的实例
        System.out.println("13: " + localTime5.withMinute(3));
        // 更改秒数,并返回新的实例
        System.out.println("14: " + localTime5.withSecond(14));

        // 小时增加指定值,并返回新的实例
        System.out.println("15: " + localTime5.plusHours(1));
        // 分钟增加指定值,并返回新的实例
        System.out.println("16: " + localTime5.plusMinutes(1));
        // 秒数增加指定值,并返回新的实例
        System.out.println("17: " + localTime5.plusSeconds(1));

        // 小时减去指定值,并返回新的实例
        System.out.println("18: " + localTime5.minusHours(1));
        // 分钟减去指定值,并返回新的实例
        System.out.println("19: " + localTime5.minusMinutes(1));
        // 秒数减去指定值,并返回新的实例
        System.out.println("20: " + localTime5.minusSeconds(1));

        // 按照指定格式返回一个字符串
        System.out.println("21: " + localTime5.format(DateTimeFormatter.ofPattern("HH:mm:ss")));
        System.out.println("22: " + localTime5.format(DateTimeFormatter.ofPattern("HH:mm:ss.SSS")));

        // 添加一个 LocalDate 获取一个 LocalDateTime 实例
        System.out.println("23: " + localTime5.atDate(LocalDate.now()));

    }
}

输出结果:

01: 10:11:47.621
02: 10:02:15
03: 00:01:40
04: 10:01:12
05: 11:02:13.111
06: 11
07: 2
08: 13
09: true
10: false
11: false
12: 12:02:13.111
13: 11:03:13.111
14: 11:02:14.111
15: 12:02:13.111
16: 11:03:13.111
17: 11:02:14.111
18: 10:02:13.111
19: 11:01:13.111
20: 11:02:12.111
21: 11:02:13
22: 11:02:13.111
23: 2020-11-11T11:02:13.111

LocalDateTime (日期-时间)

LocalDateTime是一个不可变的日期-时间对象,通常被视为年-月-日-时-分-秒,也可以访问其他日期和时间字段,例如日期,星期。时间精度为纳秒,例如:2007年10月2日13:45:30.123456789。
通过下面的示例代码来了解其方法的使用。

示例代码:

public class LocalDateTimeDemo {

    public static void main(String[] args) {

        // 从默认时区的系统时钟获取当前日期-时间
        LocalDateTime localDateTime1 = LocalDateTime.now();
        System.out.println("01: " + localDateTime1);

        // 通过年、月、日、时、分、秒获得 LocalDateTime 的实例
        LocalDateTime localDateTime2 = LocalDateTime.of(2020, 12, 1, 10, 11, 12);
        System.out.println("02: " + localDateTime2);

        // 通过 LocalDate 和 LocalTime 获得 LocalDateTime 的实例
        LocalDateTime localDateTime3 = LocalDateTime.of(LocalDate.now(), LocalTime.now());
        System.out.println("03: " + localDateTime3);

        // 从一个文本字符串(如 2007-12-03T10:15:30)获取一个 LocalDateTime 的实例,使用默认 DateTimeFormatter.ISO_LOCAL_DATE_TIME 格式
        LocalDateTime localDateTime4 = LocalDateTime.parse("2020-12-01T10:11:12");
        System.out.println("04: " + localDateTime4);
        // 使用特定的格式化,从文本字符串获取 LocalDateTime的实例。
        LocalDateTime localDateTime5 = LocalDateTime.parse("2020-12-01 10:11:12", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println("05: " + localDateTime5);

        // 获取年
        System.out.println("06: " + localDateTime5.getYear());
        // 获取月
        System.out.println("07: " + localDateTime5.getMonthValue());
        // 获取日
        System.out.println("08: " + localDateTime5.getDayOfMonth());
        // 获取时
        System.out.println("09: " + localDateTime5.getHour());
        // 获取分
        System.out.println("10: " + localDateTime5.getMinute());
        // 获取秒
        System.out.println("11: " + localDateTime5.getSecond());

        // 是否在指定日期-时间之后
        System.out.println("12: " + localDateTime5.isAfter(localDateTime4));
        // 是否在指定日期-时间之前
        System.out.println("13: " + localDateTime5.isBefore(localDateTime4));
        // 是否与指定日期-时间相等
        System.out.println("14: " + localDateTime5.isEqual(localDateTime4));


        // 更改年份,并返回新的实例
        System.out.println("15: " + localDateTime5.withYear(2019));
        // 更改月份,并返回新的实例
        System.out.println("16: " + localDateTime5.withMonth(10));
        // 更改日期,并返回新的实例
        System.out.println("17: " + localDateTime5.withDayOfMonth(9));
        // 更改小时,并返回新的实例
        System.out.println("18: " + localDateTime5.withHour(12));
        // 更改分钟,并返回新的实例
        System.out.println("19: " + localDateTime5.withMinute(3));
        // 更改秒数,并返回新的实例
        System.out.println("20: " + localDateTime5.withSecond(14));

        // 年份增加指定值,并返回新的实例
        System.out.println("21: " + localDateTime5.plusYears(1));
        // 月份增加指定值,并返回新的实例
        System.out.println("22: " + localDateTime5.plusMonths(1));
        // 日期增加指定值,并返回新的实例
        System.out.println("23: " + localDateTime5.plusDays(1));
        // 小时增加指定值,并返回新的实例
        System.out.println("24: " + localDateTime5.plusHours(1));
        // 分钟增加指定值,并返回新的实例
        System.out.println("25: " + localDateTime5.plusMinutes(1));
        // 秒数增加指定值,并返回新的实例
        System.out.println("26: " + localDateTime5.plusSeconds(1));

        // 年份减去指定值,并返回新的实例
        System.out.println("27: " + localDateTime5.minusYears(1));
        // 月份减去指定值,并返回新的实例
        System.out.println("28: " + localDateTime5.minusMonths(1));
        // 日期减去指定值,并返回新的实例
        System.out.println("29: " + localDateTime5.minusDays(1));
        // 小时减去指定值,并返回新的实例
        System.out.println("30: " + localDateTime5.minusHours(1));
        // 分钟减去指定值,并返回新的实例
        System.out.println("31: " + localDateTime5.minusMinutes(1));
        // 秒数减去指定值,并返回新的实例
        System.out.println("32: " + localDateTime5.minusSeconds(1));

        // 按照指定格式返回一个字符串
        System.out.println("33: " + localDateTime5.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        // 获取 LocalDate 实例
        System.out.println("34: " + localDateTime5.toLocalDate());
        // 获取 LocalTime 实例
        System.out.println("35: " + localDateTime5.toLocalTime());

    }

}

输出结果:

01: 2020-11-11T10:13:04.496
02: 2020-12-01T10:11:12
03: 2020-11-11T10:13:04.496
04: 2020-12-01T10:11:12
05: 2020-12-01T10:11:12
06: 2020
07: 12
08: 1
09: 10
10: 11
11: 12
12: false
13: false
14: true
15: 2019-12-01T10:11:12
16: 2020-10-01T10:11:12
17: 2020-12-09T10:11:12
18: 2020-12-01T12:11:12
19: 2020-12-01T10:03:12
20: 2020-12-01T10:11:14
21: 2021-12-01T10:11:12
22: 2021-01-01T10:11:12
23: 2020-12-02T10:11:12
24: 2020-12-01T11:11:12
25: 2020-12-01T10:12:12
26: 2020-12-01T10:11:13
27: 2019-12-01T10:11:12
28: 2020-11-01T10:11:12
29: 2020-11-30T10:11:12
30: 2020-12-01T09:11:12
31: 2020-12-01T10:10:12
32: 2020-12-01T10:11:11
33: 2020-12-01 10:11:12
34: 2020-12-01
35: 10:11:12

Instant (时刻/时间戳)

该类表示在时间线上的时刻点。这比较适合在应用程序中记录事件的时间戳。
值得注意的是其时区默认使用的是UTC标准时区,若要在你当前时区使用,需要设置好时区。

示例代码:

public class InstantDemo {

    public static void main(String[] args) {

        // 从系统时钟获取当前时间戳,值得注意的是通过此方法获取的时间戳是基于UTC标准时区的
        Instant instant1 = Instant.now();
        System.out.println("01: " + instant1);

        // 可以通过设置时区,来获取指定时区的日期-时间
        ZonedDateTime zonedDateTime = instant1.atZone(ZoneId.systemDefault());
        System.out.println("01: " + zonedDateTime.toLocalDateTime());

        // 通过指定字符串转换为 Instant 实例
        Instant instant2 = Instant.parse("2020-11-05T11:22:33Z");
        System.out.println("03: " + instant2);

        // 是否在指定时间戳之后
        System.out.println("04: " + instant2.isAfter(instant1));
        // 是否在指定时间戳之前
        System.out.println("05: " + instant2.isBefore(instant1));

    }
}

输出结果:

01: 2020-11-11T02:23:03.870Z
01: 2020-11-11T10:23:03.870
03: 2020-11-05T11:22:33Z
04: false
05: true

Duration (时长)

基于时间的时间量,如:34.5秒。
该类你可能在SpringBoot配置中见到过,下面是一些示例:

  • "PT20.345S" -- parses as "20.345 seconds"
  • "PT15M" -- parses as "15 minutes" (where a minute is 60 seconds)
  • "PT10H" -- parses as "10 hours" (where an hour is 3600 seconds)
  • "P2D" -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
  • "P2DT3H4M" -- parses as "2 days, 3 hours and 4 minutes"
  • "P-6H3M" -- parses as "-6 hours and +3 minutes"
  • "-P6H3M" -- parses as "-6 hours and -3 minutes"
  • "-P-6H+3M" -- parses as "+6 hours and -3 minutes"

示例代码:

public class DurationDemo {

    public static void main(String[] args) {

        // 根据天获取实例
        Duration duration1 = Duration.ofDays(1);
        System.out.println("01: " + duration1);
        // 根据小时获取实例
        Duration duration2 = Duration.ofHours(10);
        System.out.println("02: " + duration2);
        // 根据分钟获取实例
        Duration duration3 = Duration.ofMinutes(20);
        System.out.println("03: " + duration3);
        // 根据秒获取实例
        Duration duration4 = Duration.ofSeconds(30);
        System.out.println("04: " + duration4);
        // 根据毫秒获取实例
        Duration duration5 = Duration.ofMillis(4000);
        System.out.println("05: " + duration5);

        // 从一个字符串中获取一个实例,如:PnDTnHnMn.nS,其中一天被认为是24小时
        Duration duration6 = Duration.parse("P2D");
        System.out.println("06: " + duration6);

    }
}

输出结果:

01: PT24H
02: PT10H
03: PT20M
04: PT30S
05: PT4S
06: PT48H

Clock (时钟)

一种时钟,使用时区提供对当前时间戳、日期和时间的访问。

Period (周期)

在ISO-8601日历系统中以日期为基础的时间,如:“2年3个月4天”。

ZoneId (时区ID)

一个时区ID,如:Europe/Paris 。

ZoneOffset (时区偏移量)

与UTC/Greenwich的时区偏移量,如:+02:00 。

Year (年)

ISO-8601日历系统中的一年,如:2007年。

YearMonth (年-月)

ISO-8601日历系统中的年月,如:2007-12。

MonthDay (月-日)

ISO-8601日历系统中的一个月日,如:12-03。

OffsetDateTime (带偏移量的日期/时间)

在ISO-8601日历系统中带UTC/Greenwich偏移的日期时间,如:2007-12-03T10:15:30+01:00。

OffsetTime (带偏移的时间)

在ISO-8601日历系统中带UTC/Greenwich偏移的时间,如:10:15:30+01:00。

ZonedDateTime (带时区的日期-时间)

ISO-8601日历系统中带有时区的日期时间,如:2007-12-03T10:15:30+01:00 Europe/Paris。

DayOfWeek (星期枚举类)

星期几,如:“星期二”。

Month (月份枚举类)

一个月份,如:“七月”。

你可能感兴趣的:(Java8新特性 | 新的日期时间API)