Java 8 - 日期和时间示例

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(266)   2023-06-26 07:54:18

开发者社区的很大一部分一直在抱怨日期和日历类。原因有很多,例如难以理解、难以使用和不灵活。日期类甚至已经过时,Java 文档建议使用 Calendar 类而不是 Date 类。最重要的是,日期比较 是错误的,我过去也遇到过这样的问题。

Java 8 date api changes

展望未来,JAVA 8 (Lambda) 有望发布新的日期和时间 API/类 (JSR-310),也称为 ThreeTen ,这只会改变您迄今为止的工作方式。这其中的一个关键部分是提供一个新的 API,该 API 更易于使用且不易出错。

它将提供一些要求很高的功能,例如:

  • 所有关键的公共类都是不可变的和线程安全的
  • 定义了其他计算领域可以采用的术语和行为
我在 2013 年 5 月 15 日写了这篇文章。现在是 2014 年 3 月 18 日,Java 8 终于发布并可供抢先体验。我已经重新验证并验证了帖子示例中的所有输出。他们像去年 5 月那样充满魅力地工作。唯一遇到的变化是在 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 类的新类是 LocalDateLocalTimeLocalDateTime

本地日期

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 个类,这些类与上述类类似,即 OffsetDateOffsetTimeOffsetDateTime .时区偏移量可以用“+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 ?

其他此类类还有 MonthMonthDayYearYearMonth 等等。

日期调整器

日期调整器是日期处理工具中另一个美观且有用的补充。它可以轻松解决以下问题:您如何找到该月的最后一天?还是下一个工作日?还是一周的周二?

让我们看看代码。

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(&quot;+03:00&quot;));
 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(&quot;+03:00&quot;));
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(&quot;Europe/Tiraspol&quot;));
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(&quot;+02:00&quot;)).isDaylightSavings(Instant.now()));
System.out.println(ZoneRules.of(ZoneOffset.of(&quot;+02:00&quot;)).isFixedOffset());

日期格式

主要通过两个类支持日期格式化,即 DateTimeFormatterBuilderDateTimeFormatterDateTimeFormatterBuilder 使用构建器模式来构建自定义模式,其中 DateTimeFormatter 提供必要的输入。

DateTimeFormatterBuilder formatterBuilder = new DateTimeFormatterBuilder();
formatterBuilder.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
				.appendLiteral(&quot;-&quot;)
				.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

相关阅读

开发者社区的很大一部分一直在抱怨日期和日历类。原因有很多,例如难以理解、难以使用和不灵活。日期类甚至已经过时,Java 文档建议使用 Calendar 类而不是 Date 类。最重要的是,日期比...
学习在 Java 中比较两个给定日期,以找出 在通用时间轴中哪个日期早,哪个日期晚。我们将看到使用以下类的日期比较示例: LocalDate、LocalDateTime 和 ZonedDateT...
在 Java 8 中,我们可以使用 class::methodName 类型语法。让我们了解不同类型的可用Java 8 中的方法引用。 1. 方法引用的类型 Java 8 允许四种类型的方法引用...
TemporalQuery 是一种查询时间对象的标准方法(LocalDate、LocalDateTime 等),用于做出更好的业务决策。在 Java 8 中,所有主要的日期时间类都实现了 Tem...
让我们看看如何在 Java 8 中将字符串转换为日期。 1)将字符串转换为ISO8601格式的日期 默认情况下,Java 日期采用 ISO8601 格式,因此如果您有任何表示 ISO8601 格...
学习验证给定字符串是否包含日期值。我们将学习 Java 7、Java 8 及更高版本中可用的各种日期验证 技术。 1. LocalDate 和 DateTimeFormatter(Java 8 ...
获取任何给定日期的第二天或前一天的 Java 示例。该示例使用旧版 java.util.Date 类以及来自 Java 8 的 java.time.LocalDate 类。 我们可以使用此示例代...
学习检查给定日期是否是 Java 中的周末。我们将学习使用 java.util.Date 检查作为以及 Java 8 java.time.LocalDate 类. 在给定的示例中,我们假设周末是...
了解 Java 中的 ZonedDateTime 类,如何创建其实例和其他用例,例如解析、格式化以及添加持续时间和时间段。 一、概述 java.time.ZonedDateTime 类,在 Ja...
学习用 Java 获取当前日期和/或时间。请注意,处理日期时间信息的适当方式在 JDK 8 前后有所不同。 对于 JDK 8 或更高版本,推荐的方法是使用 LocalDate 和 LocalTi...