Zac*_*ack -4 java date iso8601 simpledateformat datetime-parsing
我正在尝试将ISO 8601日期字符串转换为纪元时间.我该如何处理负面日期?以下代码是否正确?我应该使用其他东西而不是简单的日期格式库吗?负日期适用于BC.
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
Run Code Online (Sandbox Code Playgroud)
TL; DR:不,你的代码不正确.是的,我建议使用现代Java日期和时间API代替SimpleDateFormat.
你的第一个问题是在共同时代(BCE,"在基督面前")之前确定多年的正确性.
当我读维基百科时,ISO 8601没有明确定义如何解释该范围内的日期.这一年本身没有什么大问题:"0000年等于1 BCE",所以-1是2 BCE,-2017是2018 BCE.你可以使用通过将格里高利历延伸到1582年正式引入之前的日期而生成的公历格里高利历,但要注意这与传统上使用的儒略日历不一致,所以当你的日期时间字符串表示1月4日这不是同一天,1月4日在历史书中.此外,使用负面年份和中风公历不是ISO 8601的要求,只能通过双方协议.预订:我不知道历史书中是否有2018年1月4日BCE的定义; 我们在引入朱利安历法之前就已经回归了(由公元前46年朱利叶斯凯撒提出).
SimpleDateFormat在引入公历之前,文档没有说明它如何处理日期.它似乎依赖于Calendar与日期/时间格式化程序相关联的对象.这样的Calendar对象GregorianCalendar在大多数计算机和JVM上都是一个,但并非总是如此.所以我认为你的代码输出并不能保证在所有计算机上都是一样的.并且GregorianCalendar可以和通常不会从教皇格里儒略历前处理日期,所以我希望你得到的结果也与史书同意,但不能与ISO 8601,当它涉及到确定哪些天是1月4日,公元2018年.因此,基于这些理由,我怀疑你的结果是不正确的.
作为测试,我将代码的输出与类似使用Java日期和时间API的输出进行了比较.运行你的代码我也得到了-125818806600.所以我尝试过:
System.out.println(OffsetDateTime.parse("-2017-01-04T12:30:00+05:00")
.toInstant()
.getEpochSecond());
Run Code Online (Sandbox Code Playgroud)
这些类应该符合ISO 8601标准,所以我更喜欢这个代码而不是你的代码(它也更简单一些).我有
-125817294600
Run Code Online (Sandbox Code Playgroud)
它不一样,所以另一个迹象表明你的代码没有给出正确的结果.差异是1512000秒,相同的是17天12小时.让我先承认我不明白.我很乐意认为朱利安和格里高利历之间的差异可以解释17或18天范围内的差异.但是12个小时让我很困惑.
编辑:12小时来自您hh在格式模式字符串中使用小写.由于您没有AM/PM标记,因此应使用大写HH.更正此错误,代码的输出是
-125818763400
Run Code Online (Sandbox Code Playgroud)
现在你的代码和我的代码之间的差异是1468800秒或恰好17天.
hh在AM或PM范围内,在1-12范围内持续数小时.大写HH是一天一小时,0-23.这是一个非常常见的错误SimpleDateFormat(不是现代课程,他们抓住它,所以你纠正它).它常常被忽视,因为大多数时间结果都是一样的; SimpleDateFormat很高兴使用AM作为默认值并解析例如14:30并将其理解为下午2:30.但由于你的字符串中的小时数恰好是12,所以有区别:12:30 AM表示当天0:30,其中ISO 12:30表示12:30 PM.因此12小时的错误.
| 归档时间: |
|
| 查看次数: |
757 次 |
| 最近记录: |