12.1 LocalDate、LocalTime、Instant、Duration以及Period
12.1.1 使用LocalDate和LocalTime
java.time.LocalDate
类提供了日期,不包含当天的时间信息,同时也不涉及时区信息。
实例是一个不可变对象,创建一个指定的日期及读取常用的值。
LocalDate date = LocalDate.of(2014, 3, 18); // 2014-03-18
int year = date.getYear(); // 2014
Month month = date.getMonth(); // MARCH
int day = date.getDayOfMonth(); // 18
DayOfWeek dayOfWeek = date.getDayOfWeek(); // 3
int len = date.lengthOfMonth(); // 31
boolean leap = date.isLeapYear(); // false
获取今天的日期
LocalDate today = LocalDate.now();
java.time.LocalDate#public int get(TemporalField field)
,获取日期的常用数值
LocalDate date = LocalDate.of(2014, 3, 18); // 2014-03-18
int year = date.get(ChronoField.YEAR); // 2014
int month = date.get(ChronoField.MONTH_OF_YEAR); // 3
int day = date.get(ChronoField.DAY_OF_MONTH); // 18
java.time.LocalTime
类提供了时间,不包含当天的日期信息,同时也不涉及时区信息。
实例是一个不可变对象,创建一个指定的时间及读取常用的值。
LocalTime time = LocalTime.of(13, 45, 20, 1); // 13:45:20.000000001
int hour = time.getHour(); // 13
int minute = time.getMinute(); // 45
int second = time.getSecond(); // 20
int nano = time.getNano(); // 1
解析字符串创建实例
LocalDate date = LocalDate.parse("2014-03-18");
LocalDate date2 = LocalDate.parse("2014-03-18", DateTimeFormatter.ISO_LOCAL_DATE);
LocalDate date3 = LocalDate.parse("2014.03.18", DateTimeFormatter.ofPattern("yyyy.MM.dd"));
LocalTime time = LocalTime.parse("13:45:20.000000001");
LocalTime time2 = LocalTime.parse("13:45:20.000000001", DateTimeFormatter.ISO_LOCAL_TIME);
// 自定义格式,需字符严格匹配
LocalTime time3 = LocalTime.parse("13_45_20.000000001", DateTimeFormatter.ofPattern("HH_mm_ss.SSSSSSSSS"));
12.1.2 合并日期和时间
java.time.LocalDate
和java.time.LocalTime
组合为java.time.LocalDateTime
,包含日期和时间信息,不涉及时区信息。
实例是一个不可变对象,基于LocalDate和LocalTime创建LocalDateTime:
LocalDateTime dt1 = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45, 20); // 2014-03-18T13:45:20
LocalDate date = LocalDate.of(2014, Month.MARCH, 18);
LocalTime time = LocalTime.of(13, 45, 20);
LocalDateTime dt2 = LocalDateTime.of(date, time); // 2014-03-18T13:45:20
LocalDateTime dt3 = date.atTime(13, 45, 20); // 2014-03-18T13:45:20
LocalDateTime dt4 = date.atTime(time); // 2014-03-18T13:45:20
LocalDateTime dt5 = time.atDate(date); // 2014-03-18T13:45:20
通过LocalDateTime创建LocalDate和LocalTime
LocalDate date1 = dt1.toLocalDate(); // 2014-03-18
LocalTime time1 = dt1.toLocalTime(); // 13:45:20
12.1.3 机器的日期和时间格式
2014-03-18T13:45:20上述格式,作为人类表达日期和时间的习惯。
但从计算机的角度,最自然的数据格式是时间戳,以Unix元年时间(UTC时区1970-01-01T00:00:00)开始所经历的秒数进行计算。
java.time.Instant
提供了时间点,涉及时区信息,实例是一个不可变对象。
Instant.ofEpochSecond(3); // 1970-01-01T00:00:03Z
Instant.ofEpochSecond(3, 0); // 1970-01-01T00:00:03Z
Instant.ofEpochSecond(2, 1_000_000_000); // 1970-01-01T00:00:03Z
Instant.ofEpochSecond(4, -1_000_000_000); // 1970-01-01T00:00:03Z
其中Z means "zero hour offset" also known as "Zulu time" (UTC).
java.time.Instant#public int get(TemporalField field)
,获取秒数、微秒、纳秒。
仅支持ChronoField中的NANO_OF_SECOND, MICRO_OF_SECOND, MILLI_OF_SECOND
12.1.4 定义Duration或Period
LocalDate,LocalTime,LocalDateTime,Instant都实现了Temporal接口——读取和操纵为时间建模的对象的值。时间点之间为时长。
java.time.Duration
衡量秒级别的长度,不支持LocalDate,此外LocalDateTime和Instant不能混合比较。
Duration d1 = Duration.between(LocalTime.now(), LocalTime.now()); // PT0S
Duration d2 = Duration.between(LocalDateTime.now(), LocalDateTime.now()); // PT0S
Duration d3 = Duration.between(Instant.now(), Instant.now()); // PT0S
其中T是分隔符,S是秒
直接创建Duration
Duration threeMinutes = Duration.of(3, ChronoUnit.MINUTES); // PT3M
java.time.period
衡量天级别的长度,不支持LocalTime,此外LocalDateTime和Instant不能混合比较。
Period p1 = Period.between(LocalDate.now(), LocalDate.now()); // P0D
其中D是天数
直接创建Period
Period tenDays = Period.ofDays(10); // P10D
Period threeWeeks = Period.ofWeeks(3); // P21D
Period twoYearsSixMonthsOneDay = Period.of(2, 6, 1); // P2Y6M1D
上述时间-日期相关的对象都是不可变的,能更好地支持函数式编程,确保线程安全,保持领域模式一致性。