计算java日期的时间时为负值

计算java日期的时间时为负值,java,datetime,Java,Datetime,只是一个我做错了什么的问题。我有以下代码: public static int berechneSekundenwert(String datum, String zeit) throws ParseException { Date dt = new Date(); SimpleDateFormat df = new SimpleDateFormat( "dd.MM.yyyy HH:mm:ss" ); dt = df.parse( datum+" "+ zeit

只是一个我做错了什么的问题。我有以下代码:

    public static int berechneSekundenwert(String datum, String zeit) throws ParseException {

    Date dt = new Date();
    SimpleDateFormat df = new SimpleDateFormat( "dd.MM.yyyy HH:mm:ss" );
    dt = df.parse( datum+" "+ zeit); 
    int gesamtzeit = (int)dt.getTime();
    return gesamtzeit;
}
现在我的导入格式是:

  • 2019年11月9日01:30:17

    我想做的是计算这些日期经过的时间,所以我 以后可以按时间对它们进行排序。但我得到了负值

    输出示例(经过的时间、日期、白天):

    • -2120215336 30.09.2019 12:03:35
    • 1757321960 25.09.2019 16:06:25
    • -211132336 30.09.2019 14:31:48
    • -1281127040 21.08.2019 12:05:36
    • -1280681040 21.08.2019 12:13:02
    • 377782960 09.09.2019 16:54:06
    • 1301386664 09.11.2019 01:30:17
    • 710621960 13.09.2019 13:21:25
    • 712564960 13.09.2019 13:53:48
因为java声明,getTime函数度量自1970年1月1日以来的时间,所以它们不都应该是肯定的吗


有人知道我做错了什么吗?

为什么要下调
getTime()
的返回值

只需让方法返回
long
,而不是
int

然后换掉这条线

int gesamtzeit = (int)dt.getTime();


计算机用一种叫做a的东西来表示日期。在Java中,将从
1970-01-01T00:00:00.000Z
到相关日期为止经过的毫秒数返回为
long
(64位整数)

在给出的代码中,该值被缩小为
int
(32位整数)。通过将
long
缩窄为
int
,最高32位被截断。
int
表示的最大值为。快速计算表明:

(2^31 - 1)      (milliseconds)
/ 1000          (milliseconds per second)
/ 60            (seconds per minute)#
/ 60            (minutes per hour)
/ 24            (hours per day)
= 24.8551348032 (days)
这意味着大约25天后,
int
(如中所定义)。更不用说,稍后的时间点的值可能低于较早的时间点,因此为负值

为了解决这个问题,我建议将
gesamtzeit
定义为
long


关于您的代码,请注意两点:

  • java.util.Date
    被视为过时。我建议改用
  • 我建议在源代码中使用英语,唯一的例外是你使用的领域特定的单词不能(很好地)翻译成英语
1这只是一个临时修复。所有具有固定位数的表示最终都会溢出。事实上,所有具有任何内存约束的表示最终都会溢出。我让读者自己决定64位整数何时溢出

tl;博士
  • 看看对
  • 只使用现代的java.time类,不要使用
    Date
    /
    SimpleDataFormat
  • 考虑or的关键问题
  • 让数据发布者了解(a)包括分区/偏移信息和(b)使用标准格式的重要性
代码:

看这个

1573263017000

细节 解决了您关于为什么使用无效负数的具体问题。但你还有其他问题

ISO 8601 现在我的导入格式是:09.11.2019 01:30:17

我建议您向这些数据的发布者介绍在以文本形式传递日期时间值时要使用的标准定义格式

传统日期时间类 您正在使用可怕的日期时间类,这些类在几年前被JSR310中定义的现代java.time类所取代。切勿使用
日期
简化格式

瞬间 显然,您希望获得UTC中1970年第一个时刻的历元引用以来的毫秒计数。但这样做需要一个时刻,一个时间线上的特定点

您的输入不符合此要求。您的输入是一天中的日期和时间,但缺少UTC或时区偏移量的上下文

因此,以您的
09.11.2019 01:30:17
为例。我们不知道这是日本东京下午1:30,还是法国巴黎下午1:30,还是美国俄亥俄州托莱多下午1:30,这都是非常不同的时刻,在时间线上相隔几个小时

因此,我们必须首先将您的输入解析为一个。此类表示没有任何偏移或分区概念的日期和时间

String input = "09.11.2019 01:30:17" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd.MM.uuuu HH:mm:ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
也许您确实知道该数据发布者想要的偏移量或区域。如果是:

  • 建议此数据的发布者在其数据中包含分区/偏移信息
  • 申请a获得a,或申请a获得a
也许您确实知道此输入是针对UTC的,即零小时分秒的偏移量

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
要获取自1970-01-01T00:00Z以来的毫秒计数,请转换为基本构造块类

自纪元开始的毫秒数的查询

long millisSinceEpoch = instant.toEpochMilli() ;
了解您的原始代码忽略了时区和UTC偏移的关键问题。因此,您的代码隐式地应用JVM的当前默认时区。这意味着您的结果在运行时会有所不同,也意味着您可能有不正确的结果


关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

该项目现已启动,建议迁移到类

您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*

从哪里获得java.time类

  • 、和更高版本-标准Java API的一部分,带有捆绑实现。
    • Java9添加了一些次要功能和修复
    • 大多数java.time功能都在中向后移植到Java6和Java7
    • 更高版本的Android捆绑包实现了java.time类

    • 对于早期的Android(嗯……您可以向下转换时间戳(
      (int)dt.getTime();
      ),它是一个64位
      长的OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
      
      Instant instant = odt.toInstant() ;
      
      long millisSinceEpoch = instant.toEpochMilli() ;