Java中比较日期:教程

导航至

很难找到完全不涉及时间操作的应用程序。具体来说,日期比较在调度、事件管理、供应和物流等领域至关重要。这适用于所有编程语言,但在这篇文章中,我们将为您介绍Java日期比较指南。

我们将首先简要介绍Java中可用的两个日期和时间API,以及为什么新API随着Java 8的发布而推出。然后,我们将进入教程,向您展示如何在Java中比较日期。

让我们开始吧。

两个日期/时间API的故事

在Java中,您有两个API——两组类和方法——用于进行时间操作。旧的一个由来自 java.util 包的类组成,例如 DateCalendar。新的API——Java时间API——提供了一个属于 java.time 包的类数组,以更全面、更稳健地处理时间。

为什么Java开发者引入了新的API?简而言之,旧的API存在许多问题,包括

  • 可变的类,因此不是线程安全的。
  • 设计不足,缺乏处理时间所需处理常见概念的类型。
  • 缺少对时区处理逻辑的支持。

正如我们提到的,Java时间API随着Java 8的发布而引入,并且自那时起一直被推荐用于Java中的时间处理。在本教程中,我们将使用新的API进行大多数示例。截至本文撰写时,我已在机器上安装了Java 21,这是最新的LTS(长期支持)版本。

为了全面起见,我们将简要介绍.util.Datejava.util.Calendar 类,但它们不应用于新的开发。

无需多言,让我们深入研究。

如何在Java中比较两个日期?

Java时间API的一个有趣方面是它提供了许多不同的类型,每种类型代表日期和时间的不同方面。因此,我们将一次教授您Java日期比较的类型。

Java LocalDate类

LocalDate 类代表没有时间组件的日期。“本地”后缀表示它与创建它的上下文相关联。它没有任何关于时区的信息,例如。

让我们看看如何创建两个实例并比较它们

var a = LocalDate.of(2024, 2, 5);

var b = LocalDate.of(2024, 2, 6);

System.out.println(a.isEqual(b) ? "Same" : "Different");

if (a.isBefore(b)) {

` System.out.println(“‘a’ comes before ‘b’”);`

}

解释上述代码

  • 首先,我们创建了两个 LocalDate 对象,分别设置为2024年2月5日和2024年2月6日。
  • 然后,我们使用 isEqual() 方法比较它们是否相等,结果显示“不同”。
  • 最后,我们使用 isBefore() 方法验证一个日期是否在另一个日期之前。

不出所料,还有一个 isAfter() 方法我们可以使用。

Java LocalTime类

LocalTime 类与 LocalDate 类类似;它只代表本地时间,没有日期组件。与它的日期对应物类似,它没有任何关于时区的认识。

让我们看看如何实例化这个类。

var t1 = LocalTime.of(8, 0, 0);

var t2 = LocalTime.of(8, 0, 1);

比较方面呢?可用的方法相同(isEqual()isBefore()isAfter())。

Java LocalDateTime类

LocalDateTime 类存储了日期和时间数据。让我们看看您如何获取一个闪亮的新的 LocalDateTime 对象

var now = LocalDateTime.now();

var tomorrow = now.plusDays(1);

var date = LocalDateTime.of(2024, 2, 5, 8, 0, 1);

var date2 = LocalDateTime.of(2024, 2, 5, 8, 0, 1);

对于比较呢?这里也适用相同的方法集。

Java Duration类

Duration 类代表时间的持续时间,例如 5 分钟、10 小时等。以下是一些创建两个对象的代码示例:

Duration sixtyMinutes = Duration.ofMinutes(60);

Duration oneHour = Duration.ofHours(1);

这次我抑制了 C# 开发者的冲动,没有使用类型推断。如您所见,我们使用 ofMinutes() 静态工厂方法创建了一个对象,另一个使用 ofHours() 方法。这两个对象是等效的,我们应该能够通过比较来证明这一点。与之前的类不同,Duration 类没有 isEqual() 方法。

因此,我们不得不求助于默认的 equals() 方法

if (oneHour.equals(sixtyMinutes)) {

` System.out.println(“Equals”);`

} else {

` System.out.println(“Different”);`

}

很棒,但如果你要比较两个持续时间以确定哪个更长呢?这正是 compareTo() 方法派上用场的地方。该方法返回 0 如果值相等,1 如果调用该方法的值更长,如果传入参数的值更长则返回 -1。您需要示例吗?

Duration someDuration = Duration.ofMinutes(60);

Duration anotherDuration = Duration.ofMinutes(70);

var result = someDuration.compareTo(anotherDuration);

switch (result)

{

` case 0:`

` System.out.println(“They’re equal.”);`

` break;`

` case 1:`

` System.out.println(“First duration is longer.”);`

` break;`

` case -1:`

` System.out.println(“Second duration is longer.”);`

` break;`

}

运行上面的代码,您将看到显示“Second duration is longer。”

Java Period 类

Period 类与 Duration 类类似,代表时间间隔。但它们之间有什么区别呢?简而言之,Period 类代表基于日历的时间间隔,如“两个月”、“一年”等。

以下是一个示例,将有助于澄清。在下面的代码中,我将

  • 实例化一个 LocalDate 对象
  • 创建一个表示一个月的 Period 对象
  • Period 对象添加到 LocalDate 并验证结果

LocalDate januaryFirst = LocalDate.of(2024, 1, 1);

Period oneMonth = Period.ofMonths(1);

LocalDate janFirstPlusOneMonth = januaryFirst.plus(oneMonth);

System.out.println(janFirstPlusOneMonth); // 显示 "2024-02-01"

我认为您会同意上面的结果并不令人惊讶。现在让我们调整示例,将开始日期改为 2 月 1 日。

LocalDate febFirst = LocalDate.of(2024, 2, 1);

Period oneMonth = Period.ofMonths(

LocalDate febFirstPlusOneMonth = febFirst.plus(oneMonth);

System.out.println(febFirstPlusOneMonth); // 显示 "2024-03-01"

您可能对上面的结果感到惊讶,也可能没有。也许您不明白我在说什么,那么我会明确指出。从 1 月 1 日到 2 月 1 日,我们有 31 天。从 2 月 1 日到 3 月 1 日,我们有 29 天——当然,通常情况下是 28 天,但 2024 年是闰年。

发生的事情是,我们上面创建的 Period 对象并不关心一个月有 28、29、30 或 31 天。它只是代表人类中心,基于日历的一个月的概念。《LocalDate》的 plus() 方法足够智能,可以确定在生成新值时应有效添加多少天。

在上述所有警告之后,如何比较时间段呢?没有什么令人惊讶的:有 equals()compareTo() 方法,并且它们的工作方式与预期一致。

Period p1 = Period.ofMonths(1);

Period p2 = Period.parse("P1M");

if (p1.equals(p2)) {

` System.out.println("当然它们是相等的");`

}

在上面的例子中,对于第二个值,我采用了不同的方法:根据ISO-8601标准格式解析了表示年分的文本表示。我只是为了增加一些多样性,但结果是相同的。

过去的日子:Date和Calendar类

正如你在本文中了解到的,Java 8引入了全新的日期和时间API。自那时起已经有十年了,我建议你使用这些新类来处理所有的时间需求。

尽管如此,你可能会在旧API的遗留代码中遇到困难,因此熟悉java.util类可能会有所帮助。

让我们看看比较两个日期的例子

Calendar feb10Calendar = new GregorianCalendar(2024, Calendar.FEBRUARY, 10);

Calendar feb15Calendar = new GregorianCalendar(2024, Calendar.FEBRUARY, 15);

Date date1 = feb10Calendar.getTime();

Date date2 = feb15Calendar.getTime();

if (date1.equals(date2)) {

` System.out.println("它们是相同的");`

} else {

` System.out.println("它们不是相同的");`

}

var comp = date1.compareTo(date2);

switch (comp)

{

` case 0:`

` System.out.println("它们是相同的");`

` break;`

` case 1:`

` System.out.println("第一个日期在第二个日期之后");`

` break;`

` case -1:`

` System.out.println("第二个日期在第一个日期之后");`

` break;`

}

上面的代码无需过多解释,因为比较看起来与之前的例子相同,只是创建日期需要更多的仪式

Java日期比较:正确的方式

处理时间是编程中的日常任务,但它比许多开发者所认为的要复杂。这在所有编程语言中都是如此:PythonC#、Java——它们都很复杂。

在本文中,我们探讨了时间处理的一个特定方面:Java日期比较。Java 8引入了一个丰富的新的时间API,提供了许多表示日期和时间不同方面的类。正如你所看到的,使用Java时间API比较日期非常简单。如果你将时间戳数据作为应用程序的关键部分,那么检查InfluxDBJava客户端库可能值得考虑,这使你在Java中存储和查询数据变得容易。

本文由Carlos Schults撰写。 Carlos是一位熟练的软件工程师,也是一位资深的为各种客户编写技术文档的作家。他的热情是深入探究(原始来源)并使用易于理解且信息丰富的技术内容吸引读者。