【问题标题】:Best way to get maximum Date value in java?在java中获得最大日期值的最佳方法?
【发布时间】:2009-11-16 18:31:22
【问题描述】:

我正在编写一些逻辑,要求将空日期视为未来永远的意义(所讨论的日期是到期日期,可能存在也可能不存在)。我不想在整个代码中为 null 日期添加特殊情况,而是只想将 null 转换为最大可能的日期。我没有看到任何明显的方法来获得这样的价值,而无需对其进行硬编码。获得正在使用的任何 Date 实现的最大值的最佳方法是什么?

【问题讨论】:

  • 对于 Joda-Time,请参阅 this similar Question
  • 对此没有好的答案,因为 (a) 最大值和 (b) 日期时间值的粒度因编程语言、库、数据库等而异。我建议任意选择一个足够远的硬编码值,以确保它比你的应用程序寿命更长,但不要太远以至于超出任何组件的限制。类似2666-01-01T00:00:00.0Z

标签: java datetime


【解决方案1】:

试试

new Date(Long.MAX_VALUE)

这应该在 Java 中为您提供最长的日期值。

【讨论】:

  • 只是在这里扮演魔鬼的拥护者......该解决方案仍然对 Date 对象的实现做出假设。如果我的代码在遥远的将来某个时候在 java 版本 9 中编译,Date 被升级为能够表示年份 quattuordecillion,但是需要很长时间的构造函数被限制为原始的 64 位日期范围......
  • 大声笑......好吧,在这种情况下,至少 Date 值在未来很远,无论哪种方式都应该被认为是无法访问的。当前 Java 6 impl 下的“Sun Aug 17 00:12:55 MST 292278994”。如果您的代码仍在 292278994 中,我会印象深刻。:-)
  • 我同意其他答案之一,即这段代码应该包装在另一个辅助类中,而不是直接使用。
  • 仅当 TimeZone 设置为 UTC 时
  • jthg:不会的,Sun 喜欢保持 JDK API 向后兼容,并且他们正在开发基于 joda-time 的新日期/时间 API(JSR-310)。
【解决方案2】:

+1 Long.MAX_VALUE 建议。如果您按日期字段对内容进行排序,这似乎会对您有所帮助。

但是,不要在需要日期的地方从某个较大的常量值构造日期,而是使用全局可见的单例来保存代表您的特殊值的 Date 实例:

class DateUtil
{
  public static final Date NO_EXPIRE = new Date( Long.MAX_VALUE );
}

然后您可以使用简单的身份比较 (mydate == DateUtils.NO_EXPIRE) 来测试特定日期是否属于您的特殊情况,而不是 obj.equals(); (即mydate.equals(DateUtils.NO_EXPIRE);)

【讨论】:

  • 这仍然不会为您提供最大日期值,除非您包含 UTC 时区!
  • @JarrodRoberson 不正确,时区无关紧要。 java.util.Date 始终采用 UTC。这个答案正确地确定了可以由 java.util.Date 对象表示的最后时刻。我对您的评论还有其他方面的误解吗?
【解决方案3】:

从 Java SE 8 开始,您可以使用:

LocalDate.MAX

【讨论】:

    【解决方案4】:

    在你自己的类中封装你想要的功能,使用 Long.MAX_VALUE 很可能会给你带来问题。

    class ExpirationDate {
        Date expires;
    
        boolean hasExpiration() {
            return expires == null;
        }
    
        Date getExpirationDate() {
            return expires;
        } 
    
        boolean hasExpired(Date date) {
            if (expires == null) {
                return true;
            } else {
                return date.before(expires);
            }
        }
    
        ...
    }
    

    【讨论】:

    • +1;这将导致未来的过期检查更具可读性。
    • 我需要的逻辑只适用于单个方法中的代码,所以我认为这是不必要的。
    • 我会反其道而行之。在我看来, expires==null 意味着没有过期时间,所以任何日期都是合法的。
    【解决方案5】:

    也许一种选择是使用最大系统日期。您可以通过以下方式获得它:

    System.out.println(new Date(Long.MAX_VALUE).toString())
    //Output:
    //Sun Aug 17 12:42:55 IST 292278994
    

    【讨论】:

      【解决方案6】:

      这是我的工作:

      public static final TimeZone UTC;
      
      // 0001.01.01 12:00:00 AM +0000
      public static final Date BEGINNING_OF_TIME;
      
      // new Date(Long.MAX_VALUE) in UTC time zone
      public static final Date END_OF_TIME;
      
      static
      {
          UTC = TimeZone.getTimeZone("UTC");
          final Calendar c = new GregorianCalendar(UTC);
          c.set(1, 0, 1, 0, 0, 0);
          c.set(Calendar.MILLISECOND, 0);
          BEGINNING_OF_TIME = c.getTime();
          c.setTime(new Date(Long.MAX_VALUE));
          END_OF_TIME = c.getTime();
      }
      

      请注意,如果 TimeZone 不是 UTC,您将获得“时间结束”的偏移量,这不是最大值。这些对于插入数据库字段并且不必具有 NULL 日期特别有用。

      【讨论】:

      • 如果我处理的所有日期都在同一个时区,这真的很重要吗? 'new Date(Long.MAX_VALUE)' 将获取当前时区的最大日期。
      • 除非您的 TimeZone 是 UTC,否则您不会真正获得最大 Date 对象。
      【解决方案7】:

      您是否考虑过采用Joda Time

      它计划包含在 java 7 中作为 JSR-310 的基础

      您可能感兴趣的功能是ZeroIsMaxDateTimeField 这基本上将零字段交换为日期时间内该字段的最大值。

      【讨论】:

        【解决方案8】:

        我看到的一个问题是,对于到期日期排序,使用 null 不容易排序。因此,可能需要用实际值替换(即使它是未来的任意哨兵值)。

        我想另一种处理“没有到期”的方法是简单地说某事在未来 100 年到期......除非您的数据库正在处理长期合同!

        【讨论】:

          【解决方案9】:

          我喜欢 Instant.MAX,因为它比 Long.MAX_VALUE 更可能在未来得到支持。

          请注意,从今天开始,Instant.MAX.toEpochMilli() 会引发溢出错误。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-01-18
            • 1970-01-01
            • 2013-11-13
            • 1970-01-01
            相关资源
            最近更新 更多