yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'转换为日期格式

时间:2017-05-26 17:46:08

标签: java android date datetime datetime-format

我以这种格式从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

如何正确转换原始日期?

3 个答案:

答案 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());