开发者社区的很大一部分一直在抱怨日期和日历类。原因有很多,例如难以理解、难以使用和不灵活。日期类甚至已经过时,Java 文档建议使用 Calendar
类而不是 Date
类。最重要的是,日期比较 是错误的,我过去也遇到过这样的问题。
展望未来,JAVA 8 (Lambda) 有望发布新的日期和时间 API/类 (JSR-310),也称为 ThreeTen ,这只会改变您迄今为止的工作方式。这其中的一个关键部分是提供一个新的 API,该 API 更易于使用且不易出错。
它将提供一些要求很高的功能,例如:
TemporalAdjuster.java
中。以前它是一个类,现在它是一个@FunctionalInterface
。因此,我已经更正了相关示例并使用了类“TemporalAdjusters.java
”。
Table of Contents New classes to represent local date and timezone New classes to represent timestamp and duration Added utility classes over existing enums Date adjusters introduced Building dates will be easier New class to simulate system/machine clock Timezone handling related changes Date formatting changes References
旨在取代 Date 类的新类是 LocalDate
、LocalTime
和 LocalDateTime
。
LocalDate 类表示日期。没有时间或时区的表示。
LocalDate localDate = LocalDate.now(); System.out.println(localDate.toString()); //2013-05-15 System.out.println(localDate.getDayOfWeek().toString()); //WEDNESDAY System.out.println(localDate.getDayOfMonth()); //15 System.out.println(localDate.getDayOfYear()); //135 System.out.println(localDate.isLeapYear()); //false System.out.println(localDate.plusDays(12).toString()); //2013-05-27
LocalTime 类表示时间。没有日期或时区的表示。
//LocalTime localTime = LocalTime.now(); //toString() in format 09:57:59.744 LocalTime localTime = LocalTime.of(12, 20); System.out.println(localTime.toString()); //12:20 System.out.println(localTime.getHour()); //12 System.out.println(localTime.getMinute()); //20 System.out.println(localTime.getSecond()); //0 System.out.println(localTime.MIDNIGHT); //00:00 System.out.println(localTime.NOON); //12:00
LocalDateTime 类表示日期时间。没有时区的表示。
LocalDateTime localDateTime = LocalDateTime.now(); System.out.println(localDateTime.toString()); //2013-05-15T10:01:14.911 System.out.println(localDateTime.getDayOfMonth()); //15 System.out.println(localDateTime.getHour()); //10 System.out.println(localDateTime.getNano()); //911000000
如果您想使用带区域信息的日期功能,那么 Lambda 会为您提供额外的 3 个类,这些类与上述类类似,即 OffsetDate
、OffsetTime
和 OffsetDateTime
.时区偏移量可以用“+05:30”或“欧洲/巴黎”格式表示。这是通过使用另一个类完成的,即 ZoneId
。
OffsetDateTime offsetDateTime = OffsetDateTime.now(); System.out.println(offsetDateTime.toString()); //2013-05-15T10:10:37.257+05:30 offsetDateTime = OffsetDateTime.now(ZoneId.of("+05:30")); System.out.println(offsetDateTime.toString()); //2013-05-15T10:10:37.258+05:30 offsetDateTime = OffsetDateTime.now(ZoneId.of("-06:30")); System.out.println(offsetDateTime.toString()); //2013-05-14T22:10:37.258-06:30 ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Paris")); System.out.println(zonedDateTime.toString()); //2013-05-15T06:45:45.290+02:00[Europe/Paris]
为了表示任何时刻的特定时间戳,需要使用的类是 Instant< /a>。 Instant
类表示精确到纳秒级的瞬间。 Instant
上的操作包括与另一个 Instant
的比较以及添加或减去持续时间。
Instant instant = Instant.now(); System.out.println(instant.toString()); //2013-05-15T05:20:08.145Z System.out.println(instant.plus(Duration.ofMillis(5000)).toString()); //2013-05-15T05:20:13.145Z System.out.println(instant.minus(Duration.ofMillis(5000)).toString()); //2013-05-15T05:20:03.145Z System.out.println(instant.minusSeconds(10).toString()); //2013-05-15T05:19:58.145Z
Duration类是java语言中首次引入的全新概念。它表示两个时间戳之间的时间差。
Duration duration = Duration.ofMillis(5000); System.out.println(duration.toString()); //PT5S duration = Duration.ofSeconds(60); System.out.println(duration.toString()); //PT1M duration = Duration.ofMinutes(10); System.out.println(duration.toString()); //PT10M duration = Duration.ofHours(2); System.out.println(duration.toString()); //PT2H duration = Duration.between(Instant.now(), Instant.now().plus(Duration.ofMinutes(10))); System.out.println(duration.toString()); //PT10M
Duration
处理小的时间单位,例如毫秒、秒、分钟和小时。它们更适合与应用程序代码交互。
要与人互动,您需要获得更大的持续时间,这些持续时间以 Period类。
Period period = Period.ofDays(6); System.out.println(period.toString()); //P6D period = Period.ofMonths(6); System.out.println(period.toString()); //P6M period = Period.between(LocalDate.now(), LocalDate.now().plusDays(60)); System.out.println(period.toString()); //P1M29D
当前的 Java SE 平台使用 int 常量表示月份、星期几和 am-pm 等。现在添加了许多额外的实用程序类,这些类在这些枚举之上工作。我正在举一个这样的例子 DayOfWeek。此类是日期枚举的包装器,也可以与其他类一致地使用。
//day-of-week to represent, from 1 (Monday) to 7 (Sunday) System.out.println(DayOfWeek.of(2)); //TUESDAY DayOfWeek day = DayOfWeek.FRIDAY; System.out.println(day.getValue()); //5 LocalDate localDate = LocalDate.now(); System.out.println(localDate.with(DayOfWeek.MONDAY)); //2013-05-13 i.e. when was monday in current week ?
其他此类类还有 Month
、MonthDay
、Year
、YearMonth
等等。
日期调整器是日期处理工具中另一个美观且有用的补充。它可以轻松解决以下问题:您如何找到该月的最后一天?还是下一个工作日?还是一周的周二?
让我们看看代码。
LocalDate date = LocalDate.of(2013, Month.MAY, 15); //Today LocalDate endOfMonth = date.with(TemporalAdjusters.lastDayOfMonth()); System.out.println(endOfMonth.toString()); //2013-05-31 LocalDate nextTue = date.with(TemporalAdjusters.next(DayOfWeek.TUESDAY)); System.out.println(nextTue.toString()); //2013-05-21
现在也可以使用构建器模式 创建日期对象。构建器模式允许使用单独的部分构建您想要的对象。这是使用以“at”为前缀的方法实现的。
//Builder pattern used to make date object OffsetDateTime date1 = Year.of(2013) .atMonth(Month.MAY).atDay(15) .atTime(0, 0) .atOffset(ZoneOffset.of("+03:00")); System.out.println(date1); //2013-05-15T00:00+03:00 //factory method used to make date object OffsetDateTime date2 = OffsetDateTime. of(2013, 5, 15, 0, 0, 0, 0, ZoneOffset.of("+03:00")); System.out.println(date2); //2013-05-15T00:00+03:00
在新版本中提出了一个新类 Clock。这模拟系统时钟功能。我最喜欢这个功能。原因是在进行单元测试时。您经常需要在将来测试 API。为此,我们一直在转发下一个日期的系统时钟,然后再次重启服务器并测试应用程序。
现在,不需要这样做了。使用 Clock
类来模拟这个场景。
Clock clock = Clock.systemDefaultZone(); System.out.println(clock); //SystemClock[Asia/Calcutta] System.out.println(clock.instant().toString()); //2013-05-15T06:36:33.837Z System.out.println(clock.getZone()); //Asia/Calcutta Clock anotherClock = Clock.system(ZoneId.of("Europe/Tiraspol")); System.out.println(anotherClock); //SystemClock[Europe/Tiraspol] System.out.println(anotherClock.instant().toString()); //2013-05-15T06:36:33.857Z System.out.println(anotherClock.getZone()); //Europe/Tiraspol Clock forwardedClock = Clock.tick(anotherClock, Duration.ofSeconds(600)); System.out.println(forwardedClock.instant().toString()); //2013-05-15T06:30Z
与时区相关的处理由 3 个主要类完成。这些是 ZoneOffset,时区, ZoneRules。
ZoneOffset
类表示与 UTC 的固定偏移量(以秒为单位)。这通常表示为格式为“±hh:mm”的字符串。TimeZone
类表示定义了指定时区规则的区域的标识符。ZoneRules
是定义区域偏移何时更改的实际规则集。//Zone rules System.out.println(ZoneRules.of(ZoneOffset.of("+02:00")).isDaylightSavings(Instant.now())); System.out.println(ZoneRules.of(ZoneOffset.of("+02:00")).isFixedOffset());
主要通过两个类支持日期格式化,即 DateTimeFormatterBuilder
和 DateTimeFormatter
。 DateTimeFormatterBuilder
使用构建器模式来构建自定义模式,其中 DateTimeFormatter
提供必要的输入。
DateTimeFormatterBuilder formatterBuilder = new DateTimeFormatterBuilder(); formatterBuilder.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME) .appendLiteral("-") .appendZoneOrOffsetId(); DateTimeFormatter formatter = formatterBuilder.toFormatter(); System.out.println(formatter.format(ZonedDateTime.now()));
这些是我能够识别并致力于的重大变化。
快乐学习!!
地址:https://www.cundage.com/article/date-and-time-api-changes-in-java-8-lambda.html