【问题标题】:Min/Max Date/DateTime in JodaTimeJodaTime 中的最小/最大日期/日期时间
【发布时间】:2015-12-12 03:09:18
【问题描述】:

JodaTime 中是否有任何方法可以构造一个始终小于/大于任何其他 Date/DateTime 的 Date/DateTime?类似于

DateTime bigBang = DateTime.xxx();
DateTime endOfUniverse = DateTime.yyy();

约束:我不想使用标准的 Java 日期库。

【问题讨论】:

  • 我认为new DateTime(0) 会给你可以表示的最低DateTime。只是一个疯狂的猜测,但long 的最大值可能是最大值?
  • 使用 Java 8,它只是 LocalDateTime.MAX (resp. MIN)
  • @TheodorosChatzigiannakis 0 将给出 01/01/1970。您绝对可以在过去使用负值走得更远。但是,MIN_VALUE 和 MAX_VALUE 不是 DateTime 的有效值。它们适用于 Instant。
  • 这是不可能的......因为如果你有最大的日期时间,它总是与最大的日期时间相同。。自相矛盾哈哈。除非你的意思是smaller/larger than any other Date/DateTime besides itself
  • 国际海事组织,Joda 不应该以这种方式使用。我找到了一个方法BasicChronology.getMaxYears(),但这是一个封装方法。

标签: java jodatime


【解决方案1】:

java.time

Joda-Time 项目现在处于维护模式。团队建议迁移到 java.time 类。

对于 java.time 中的最小值/最大值,请参阅 my Answer 的类似问题。

乔达时间

Joda-Time 从UTC 中的 1970 年第一个时刻的纪元开始跟踪时间作为 milliseconds 的计数。此计数使用64-bit long 整数保持。因此,从技术上讲,最大值和最小值是 long 的 +/- 限制。

… new DateTime( Long.MIN_VALUE )
… new DateTime( Long.MAX_VALUE )

Joda-Time 没有可方便地用作常数的最小/最大值。相比之下,请注意 Joda-Time 的继任者 java.time 内置于 Java 8 及更高版本中,确实提供了常量 LocalDateTime.MIN 和 LocalDateTime.MAX。

顺便说一句,Joda-Time 团队建议我们应该迁移到 java.time。大部分 java.time 功能在 ThreeTen-Backport 中向后移植到 Java 6 和 7,在 ThreeTen-ABP 中进一步适应 Android。

太大,太小

谨防这些极端情况。它们的使用并不实用。各种库、应用程序、数据库和其他日期时间值的接收器/源可能有很大不同的限制,有些大得多,但通常小得多。

例如,许多系统使用 UNIX 和 POSIX 的旧传统跟踪时间作为自 1970-01-01T00:00:00Z 以来整秒的 32 位整数计数。 +/- 20 亿秒的自然限制导致Year 2038 Problem 迫在眉睫。

另一个限制是表单和报告中字段的物理显示大小,预计年份数字只有四位数。

解决方法

您可以定义自己的最小值/最大值。

您可能需要极端值,例如 0000 年和 9999 年。Joda-Time 支持晚于 9,999 年,但我会坚持使用 4 位数字以适应屏幕和报告中显示的常用格式。从视觉上看,四个九是一个虚假的日期。

或者您可能需要适合您的业务逻辑的预期最小值。如果构建一个新的发票系统,那么您知道年份应该始终是今年或更晚。

我建议在帮助类上定义常量。像这样的:

package com.example;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;

public class JodaTimeHelper {

    static final public DateTime START_OF_TIME = new DateTime( 0000, 1, 1, 0, 0, 0, DateTimeZone.UTC );
    static final public DateTime END_OF_TIME = new DateTime( 9999, 1, 1, 0, 0, 0, DateTimeZone.UTC );

    static final public DateTime MINIMUM_INVOICE_DATETIME = new DateTime( 2015, 1, 1, 0, 0, 0, DateTimeZone.UTC );

}

这是调用这些常量的语法。

System.out.println( "START_OF_TIME: " + JodaTimeHelper.START_OF_TIME );
System.out.println( "END_OF_TIME: " + JodaTimeHelper.END_OF_TIME );
System.out.println( "MINIMUM_INVOICE_DATETIME: " + JodaTimeHelper. MINIMUM_INVOICE_DATETIME );

运行时。

START_OF_TIME: 0000-01-01T00:00:00.000Z
END_OF_TIME: 9999-01-01T00:00:00.000Z
MINIMUM_INVOICE_DATETIME: 2015-01-01T00:00:00.000Z

【讨论】:

  • 附带说明,JodaTime 支持的极端最小/最大日期为:new DateTime(Long.MIN_VALUE);新日期时间(Long.MAX_VALUE);
【解决方案2】:

当所有日期都在同一个 TimeZone 内时,您可以创建 DateTime 对象,并将字段分配为最小值或最大值。
但是当使用这个构造函数时

DateTime(int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minuteOfHour, int secondOfMinute)

Years.MAX_VALUE.getYears() 我有以下异常:

因此,使用距异常的最大年数,我想出了以下宇宙结束日期时间:

DateTime dtMax = new DateTime(292278993, 12, 31, 23, 59, 59);
System.out.println(dtMax);
// prints 292278993-12-31T23:59:59

更多详情请见documentation。
还有一个有趣的讨论可以阅读here。

【讨论】:

  • 这取决于使用的年表。在科普特年代学中,最大年份是 292272708
  • ISOChronology 用于上述示例。
【解决方案3】:

在阅读了许多不同的切线之后,我最终决定找出一个适用于 UTC 时区的最小值和最大值的最小情况。事实证明,尝试使用Long 的MIN_VALUE 和MAX_VALUE 会向我发送兔子踪迹。

所以,给定以下代码sn-p:

new DateTime(milliseconds, DateTimeZone.UTC)

以下是适用于 milliseconds 的最小/最大值(在 Java 1.7 中测试):

UTC_DATE_TIME_MIN_VALUE_IN_MILLIS = 9223372017129599999L
UTC_DATE_TIME_MAX_VALUE_IN_MILLIS = -9223372017043200000L

这两个值都与Long.MIN_VALUE 和Long.MAX_Value 相差约200 亿。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多