核心技术Ⅱ:时间与日期 API
关于
相关类:
- Date、Time:
- LocalDate、LocalTime、LocalDateTime:
- ZonedDateTime:
时间线(Date、Time)
Java 的“Date”和“Time”API规范要求Java使用的时间尺度为:
- 每天 86400 秒;
- 每天正午与官方时间精确匹配;
- 在其他时间点上,以精确定义的方式与官方时间接近匹配;
Instant:表示时间线上的某个点。
- “新纪元”:时间线原点(穿过伦敦格林威治皇家天文台的本初子午线所处时区的1970年1月1日的午夜),从该原点开始,时间按照每天86400秒向前或向回度量,精确到纳秒。
- Instant的值向回可追溯lO亿年(“Instant.MIN”),最大的值“Instant.MAX”是公元I000000000年的12月31口。
- Instant对象用作时间戳:“Instant.now()”当前的时刻;“equals”、“compareTo”比较两个Instant对象;“Duration.between”得到两个时刻之间的时间差。
Instant start = Instant.now();
runAlgorithm();
Instant end = Instant.now();
Duration timeElapsed = Duration.between(start, end);
long millis = timeElapsed.toMillis();
Duration:两个时刻之间的时间量。
- Duration对象的内部存储所需的空间超过了一个1ong的值,因此秒数存储在一个1ong中,而纳秒数存储在一个额外的int中。
- 如果想要让计算精确到纳秒级,那么需要整个Duration的存储内容;
- 如果不要求这么高的精度,可以用1ong的值来执行计算,然后直接调用“toNanos”。
- 通过调用“toNanos”、“toMi11is”、“getSeconds”、“toMinutes”、“toHours”、“toDays”,获得Duration按照传统单位度址的时间长度。
- “Instant”和“Duration”类都是不可修改的类,所以诸如“multipliedBy”和“minus”这样的方法都会返回一个新的实例。
本地时间线(LocalDate、LocalTime、LocalDateTime)
本地时间(LocalDate)
LocalDate:带有年、月、日的日期。
- 构建LocalDate对象,可以使用“now”或“of”静态方法:
LocalDatetoday = LocalDate.now(); //Today'sdate LocalDatealonzosBirthday = Loca1Date.of(1903,6,14); alonzosBirthday = Loca1Date.of(1903,Month.JUNE,14); //UsestheMonthenumeration
- 月份使用通常的月份数字(从1开始),或者使用“Month”类枚举。(UNlX和“java.util.Date”的月从0开始而年从1900开始);
- LocalDate的两个时间点之间的时长“Period”;(类比于“Instant”之间的“Duration”)
- (类比于“Instant”之间的“Duration”)
// 获取下一年的生日 birthday.plus(Period.ofYears(l)); birthday.plusYears(l); birthday.plus(Duration.ofDays(365)); // 在闰年不会产生正确结果的。
// 程序员日是每年的第 256 天
LocalDate programmersDay = Loca1Date.of(2014, 1, 1).plusDays(255);
- “util”方法会产生两个本地日期之间的时长。
independenceDay.unti1(christmas) // 会产生5个月21天的一段时长。 // 这实际上并不是很有用,因为每个月的天数不尽相同。为了确定到底有多少天,可以使用: independenceOay.until(christmas,ChronoUnit.DAYS) //174days
- “getDayOfWeek”会产生星期日期,即“DayOfWeek”枚举的某个值。
- “DayOfWeek.MONDAY”的枚举值为1,而“DayOfWeek.SUNDAY”的枚举值为7;
- “DayOfWeek”枚举具有便捷方法“plus”和“minus”,以7为模计算星期日期;
- 有些方法可能会创建出并不存在的日期。例如,在1月31日上加上1个月不应该产生2月31日。
- (这些方法并不会抛出异常,而是会返回该月有效的最后一天)
Loca1Date.of(2016,1,31).plusMonths(l); Loca1Date.of(2016,3,31).minusMonths(l); // 都将产生2016年2月29日。
- 除了LocalDate之外,还有“MonthDay”、“YearMonth”和“Year”类可以描述部分日期。
- 例如,12月25日(没有指定年份)可以表示成一个“MonthDay”对象;