我以这种格式从API收到日期:
YYYY-MM-dd'T'HH:MM:ss.SSSSSSS'Z'
并以这种方式转换它:
String rawDate = "2017-05-11T15:46:48.2226756Z";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'", Locale.getDefault());
Date date = simpleDateFormat.parse(rawDate);
System.out.println(date); //Thu May 11 16:23:54 PDT 2017
但是日期输出是这样的:
2017年5月11日星期四16:23:54
输出应该是:
2017年5月11日星期五15:46:48
如何正确转换原始日期?
答案 0 :(得分:3)
SimpleDateFormat
无法处理秒上的任何其他小数,而不是三(毫秒),因此无法正确解析字符串。此外,较新的Java日期和时间类通常更加程序员友好且方便。它们具有纳秒级精度(秒数为9位小数)。所以我建议你考虑继续他们。
如前所述,Z表示祖鲁时区,也称为UTC。所以2017-05-11T15:46:48.2226756Z
表示15:46:48 UTC,等于太平洋夏令时8:46:48。您的格式是即时的ISO 8601格式,Instant
类理解为默认格式,因此解析很简单:
Instant instant = Instant.parse(rawDate);
结果是
2017-05-11T15:46:48.222675600Z
唯一需要注意的是两个添加的零。 toString
方法以三个为一组打印小数,足够的组来呈现完整的精度。因此,使用7位小数,它会打印9。
要在太平洋时区获取日期:
ZonedDateTime dateTime = instant.atZone(ZoneId.of("America/Los_Angeles"));
结果就是我的预测:
2017-05-11T08:46:48.222675600-07:00[America/Los_Angeles]
现在假设你得到了你的原始日期 - 时间字符串来自误解的人,并且真正意味着2017年5月11日星期五15:46:48(这不是历史上的第一次)。然后你需要将其转换为。再说一次,虽然这对于老式的课程来说很麻烦,但是对于新的课程来说这很顺利:
ZonedDateTime dateTime = instant.atOffset(ZoneOffset.UTC)
.atZoneSimilarLocal(ZoneId.of("America/Los_Angeles"));
结果是你要求的那个(除了我给你所有的小数):
2017-05-11T15:46:48.222675600-07:00[America/Los_Angeles]
对于Android,您可以从ThreeTenABP库获得较新的日期和时间类。
答案 1 :(得分:1)
问题在于'S'代表毫秒。因此,在您的情况下,您告诉它时间是15小时46分48秒 2226756毫秒。如果你加上2226756毫秒,即2226秒和756毫秒到15:46:48,你的确得到16:23:54。
最简单的解决方案可能是在字符串中找到句点,然后将字符串截断三个位置,稍后将其转换为:
2017-05-11T15:46:48.222
您可以使用以下行来实现此目的:
rawDate = rawDate.substring(0, rawDate.indexOf('.') + 4);
然后用
解析它SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.getDefault());
请注意,这不能正确地围绕微秒。例如,在你的情况下,222.6756ms应该舍入到223ms,而不是下降到222ms。如果这很重要,您可以通过检查第一个丢弃的数字来手动执行此操作,以查看它是否为5或更高,并向date
添加毫秒。
更新(回复:Basil Bourque):
如果你想真正尊重你的时间字符串中的时区标识符(它表示由Ole VV在下面解释的UTC),你可以简单地在字符串的末尾添加'UTC'并用它解析它旧版Java中的时区,不使用任何其他库:
rawDate = rawDate.substring(0, rawDate.indexOf('.') + 4) + "UTC";
SimpleDateFormat sDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSz",
Locale.getDefault());
Date date = sDF.parse(rawDate);
答案 2 :(得分:-1)
您可以使用以下内容进行解析。
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());