2017-06-23 62 views
-4

我想将ISO 8601日期字符串转换为纪元时间。我如何处理负面日期?下面的代码是否正确?我应该使用别的东西而不是简单的日期格式库吗? BC的负面日期。如何在java中处理负面的ISO 8601日期字符串?

String formatString = "yyyy-MM-dd'T'hh:mm:ssX"; 
SimpleDateFormat formatter = new SimpleDateFormat(formatString); 
Date date = formatter.parse("-2017-01-04T12:30:00+05:00"); 
System.out.println(date.getTime()/1000); 

Answer: -125818806600L 
+3

什么是*负数日期*?你有哪些日历,“-2017-01-04”是哪一天的有效日期? –

+0

如果你想要在时代前一年,那么在时代一年后再做一年,否定 –

+0

请你澄清你想达到的目标 - 耶稣之前的日期? –

回答

6

TL; DR:不,你的代码是不正确的。是的,我建议使用现代Java日期和时间API而不是SimpleDateFormat

你的第一个问题是在共同时代(BCE,“基督之前”)之前定义了多年的正确性。

当我读Wikipedia时,ISO 8601没有明确定义如何解释该范围内的日期。这一年本身并没有什么大问题:“0000年等于公元前1年”,所以-1是公元前2年,-2017年是公元前2018年。您可能使用通过将公历日期延伸到1582年正式介绍之前的日期而生成的公历日历,但请注意,这不符合传统使用的Julian日历,因此当您的日期时间字符串在1月4日说明时,这是与历史书中的1月4日不同。此外,负面年份和格列高利历法的使用不是ISO 8601的要求,只能由双方达成协议。预订:我不知道历史书中是否有任何关于公元前2018年1月4日的定义;在Julian日历引入之前,我们又回来了(由Julius Caesar在公元前46年提出)。

The documentation of SimpleDateFormat没有说明在格里历日历引入之前它如何处理日期。它似乎取决于与日期/时间格式化程序关联的Calendar对象。在大多数计算机和JVM上,这样的Calendar对象将是GregorianCalendar,但并非总是如此。所以我认为你的代码的输出不能保证在所有的计算机上都是一样的。而且一个GregorianCalendar可以并且通常会处理Julian日历中教皇Gregor之前的日期,所以我预计的结果与历史书一致,但与ISO 8601不一致,当涉及到确定哪一天是公元前2018年1月4日。所以基于这些理由,我怀疑你的结果是不正确的。

作为一个测试,我比较了来自代码的输出与类似使用Java日期和时间API的输出。运行你的代码我也得到了-125818806600。所以,我想:

System.out.println(OffsetDateTime.parse("-2017-01-04T12:30:00+05:00") 
      .toInstant() 
      .getEpochSecond()); 

这些类应该是ISO 8601标准,所以我宁愿这个代码在你(这也是一个简单一点)。我得到了

-125817294600 

这是不一样的,所以另一个标志,你的代码不会给出正确的结果。差别是1512000秒,与17天12小时相同。让我首先承认我不明白。我很乐意认为朱利安和格里历的差别可能会导致17或18天的差异。但12个小时让我困惑。

编辑:12小时来自您在格式模式字符串中使用小写字母hh。由于您没有AM/PM标记,因此应使用大写HH。纠正此错误,您的代码输出为

-125818763400 

现在您的代码和我的代码之间的区别是1468800秒或17天。

hh在AM或PM范围内的小时数为1-12。大写HH用于0-23的白天。这是一个非常常见的错误SimpleDateFormat(与现代课程不同,他们抓住它,所以你纠正它)。它不经常被人注意,因为大部分时间结果都是一样的。 SimpleDateFormat很乐意使用AM作为默认值,并解析例如14:30,并将其理解为下午2:30。但是由于您的字符串中的小时数恰巧为12,因此存在差异:上午12:30意味着当天0:30,ISO 12:30意味着12:30 PM。因此,12小时的错误。

+2

仅供参考:a)SimpleDateFormat处理1582-10-15之前的日期作为Julian日历日期(一个非常简化的历史模型)。 b)在打印时,使用h而不是H(常用的时间是打算使用的)也会出现Java-8-'TimeTimeFormatter'。 c)如果输入的格式为ISO-8601格式,那么解释应该是真正的公历日历(如Java-8中所做的那样)。 –

相关问题