Java中比较日期:教程
作者:社区 / 开发者
2024年4月3日
导航至
很难找到完全不涉及时间操作的应用程序。具体来说,日期比较在调度、事件管理、供应和物流等领域至关重要。这适用于所有编程语言,但在这篇文章中,我们将为您介绍Java日期比较指南。
我们将首先简要介绍Java中可用的两个日期和时间API,以及为什么新API随着Java 8的发布而推出。然后,我们将进入教程,向您展示如何在Java中比较日期。
让我们开始吧。
两个日期/时间API的故事
在Java中,您有两个API——两组类和方法——用于进行时间操作。旧的一个由来自 java.util 包的类组成,例如 Date 和 Calendar。新的API——Java时间API——提供了一个属于 java.time 包的类数组,以更全面、更稳健地处理时间。
为什么Java开发者引入了新的API?简而言之,旧的API存在许多问题,包括
- 可变的类,因此不是线程安全的。
- 设计不足,缺乏处理时间所需处理常见概念的类型。
- 缺少对时区处理逻辑的支持。
正如我们提到的,Java时间API随着Java 8的发布而引入,并且自那时起一直被推荐用于Java中的时间处理。在本教程中,我们将使用新的API进行大多数示例。截至本文撰写时,我已在机器上安装了Java 21,这是最新的LTS(长期支持)版本。
为了全面起见,我们将简要介绍.util.Date 和 java.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日期比较:正确的方式
处理时间是编程中的日常任务,但它比许多开发者所认为的要复杂。这在所有编程语言中都是如此:Python、C#、Java——它们都很复杂。
在本文中,我们探讨了时间处理的一个特定方面:Java日期比较。Java 8引入了一个丰富的新的时间API,提供了许多表示日期和时间不同方面的类。正如你所看到的,使用Java时间API比较日期非常简单。如果你将时间戳数据作为应用程序的关键部分,那么检查InfluxDB和Java客户端库可能值得考虑,这使你在Java中存储和查询数据变得容易。
本文由Carlos Schults撰写。 Carlos是一位熟练的软件工程师,也是一位资深的为各种客户编写技术文档的作家。他的热情是深入探究(原始来源)并使用易于理解且信息丰富的技术内容吸引读者。