【问题标题】:Java Date object shows time in the futureJava Date 对象显示未来的时间
【发布时间】:2014-08-16 03:51:06
【问题描述】:

我在当前时间之前的某个时间创建了一个新的日期对象。如果我让它在今天前 1 天显示,它工作正常。但如果我想显示 30 天前,它会转到未来 (?)

Date date = new Date();
long sometime = 24 * 60 * 60 * 1000; //a day
System.out.println(date.getTime() );
Date sometimeago = new Date(date.getTime() - sometime);
System.out.println(sometimeago );
sometime = 30* 24 * 60 * 60 * 1000; //a month
sometimeago = new Date(date.getTime() - sometime);
System.out.println(sometimeago );

输出:

1408160853776
Thu Aug 14 20:47:33 PDT 2014
Thu Sep 04 13:50:21 PDT 2014

这里有什么限制?达到长期限制?

【问题讨论】:

  • 您应该查看 Calendar 类,它会为您完成大部分计算。
  • 或者更好的是新的java.time API(如果您使用的是Java 8)。或者,如果您不能,请使用 JodaTime。日子并不总是 24 小时。几个月并不总是 30 天。原来的日期/时间/日历类(以及相关的格式化程序/解析器)有很多问题。
  • 只是补充说明:阅读闰秒,24 * 60 * 60 * 1000 并不总是 1 天,请使用日历
  • 仅供参考,麻烦的旧日期时间类,如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 java.time 类取代。见Tutorial by Oracle

标签: java date datetime


【解决方案1】:

int 文字中的整数溢出,

在您的情况下,int 文字在之前被评估并导致负面结果,然后被分配给 long

sometime = 30* 24 * 60 * 60 * 1000; //a month 

这导致-1702967296

转换成

sometime = 30* 24 * 60 * 60 * 1000L; //a month 

注意:L 使其变为 long 字面量,然后相乘

最好使用Calendar 类进行Date 操作


另见

【讨论】:

  • 不应该 3030L 来强制所有计算都是多头吗?
  • @Code 如果其中任何一个是 long,则表达式将在 long 中进行评估
  • @JigarJoshi 是的,最终值为long,但有几个中间计算会导致int 并保留溢出的可能性。通过将第一个文字更改为long,所有中间结果也将是long,从而避免所有潜在的溢出错误。
【解决方案2】:

tl;博士

LocalDate.now()
         .minusDays( 1 ) 

java.time

现代的 java.time 类提供了这些功能。

如果我让它在今天前 1 天显示,

ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
LocalDate yesterday = today.minusDays( 1 ) ;

我想显示 30 天前

LocalDate thirtyDaysAgo = today.minusDays( 30 ) ;

或者您可能想要一个合乎逻辑的月份,而不是字面上的三十天。

LocalDate monthAgo = today.minusMonths( 1 ) ;

也许您想要一个日期时间而不是仅日期值。

ZonedDateTime now = ZonedDateTime.now( z ) ;
ZonedDateTime zdtYesterday = now.minusDays( 1 ) ;
ZonedDateTime zdtThirtyDaysAgo = now.minusDays( 30 ) ;
ZonedDateTime zdtMonthAgo = now.minusMonths( 1 ) ;

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-06
    • 1970-01-01
    • 2014-12-08
    • 2014-01-24
    • 2018-03-29
    • 1970-01-01
    • 2017-02-17
    • 2020-03-15
    相关资源
    最近更新 更多