简体   繁体   English

Java 日期字符串转换为不同格式但具有相同时区

[英]Java date string conversion to different format but with the same timezone

SimpleDateFormat from = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
SimpleDateFormat to = new SimpleDateFormat("MM/dd/yyyy Z");
Date date = from.parse("2017-08-10T00:00:00.000+0000");
String newDateStr = to.format(date);

The newDateStr is 08/09/2017 -0500 . newDateStr 是08/09/2017 -0500 I expect that newDataStr can have the same timezone as the original date string(0000) -- 08/10/2017 -0000 .我希望 newDataStr 可以与原始日期字符串 (0000) -- 08/10/2017 -0000 具有相同的时区。 What should I do to achieve this?我应该怎么做才能实现这一目标?

Preserving the offset from the original string is much easier with java.time , the modern Java date and time API:使用现代 Java 日期和时间 API java.time更容易保留原始字符串的偏移量:

    DateTimeFormatter from = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSZ");
    DateTimeFormatter to = DateTimeFormatter.ofPattern("MM/dd/yyyy Z");
    String newDateStr = OffsetDateTime.parse("2017-08-10T00:00:00.000+0000", from)
            .format(to);
    System.out.println(newDateStr);

This prints这打印

08/10/2017 +0000

This is not the only reason for recommending changing to the modern API.这不是建议更改为现代 API 的唯一原因。 The Date class that you are using is long outdated, and SimpleDateFormat in particular is renowned for being troublesome to work with.您使用的Date类已经过时了,尤其是SimpleDateFormat以使用麻烦而闻名。 I always recommend staying away from those classes in 2018. The modern API is generally much nicer.我总是建议在 2018 年远离这些类。现代 API 通常要好得多。 And since you are already using Java 8, there is absolutely no reason why you shouldn't want it (for anyone reading along and using Java 6 or 7, the new API has been backported to those Java versions too).并且由于您已经在使用 Java 8,因此您绝对没有理由不想要它(对于任何阅读并使用 Java 6 或 7 的人,新 API 也已向后移植到这些 Java 版本)。

What went wrong?出了什么问题?

An old-fashioned Date object is just a point in time, it doesn't hold a time zone or offset in it.老式的Date对象只是一个时间点,它不包含时区或偏移量。 So after you had parsed your string into a Date , the offset information was no longer there.因此,在您将字符串解析为Date ,偏移信息不再存在。 So neither the Date nor to , the new formatter, had any way of knowing which offset or time zone had been in the original string.因此,新的格式化程序Dateto都无法知道原始字符串中的偏移量或时区。 Instead, the new formatter used its own time zone.相反,新的格式化程序使用了自己的时区。 Since you had not explicitly set a time zone on the formatter, its time zone was that of your JVM, which apparently was a time zone that was on offset -5 from UTC on these days of September 2017.由于您没有在格式化程序上明确设置时区,因此其时区是您的 JVM 的时区,这显然是一个时区,在 2017 年 9 月的这些天与 UTC 的偏移量为 -5。

There are tricky ways to solve the problem with the outdated classes, but as I have probably said already, I wouldn't want to bother.有一些棘手的方法可以解决过时的类的问题,但正如我可能已经说过的那样,我不想打扰。

"Call requires API Level 26" for Android适用于 Android 的“调用需要 API 级别 26”

@Ponomarenko Oleh in a comment writes: @Ponomarenko Oleh 在评论中写道:

Pay attention: "Call requires API Level 26" for Android.注意:Android 的“调用需要 API 级别 26”。

However, java.time works nicely on both older and newer Android devices.但是,java.time 在较旧和较新的 Android 设备上都能很好地工作。 It just requires at least Java 6 .它只需要至少Java 6

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.在 Java 8 及更高版本和更新的 Android 设备(从 API 级别 26)中,现代 API 是内置的。 This is also the intended meaning of the message quoted in the comment.这也是评论中引用的消息的预期含义。
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).在非 Android Java 6 和 7 中获得 ThreeTen Backport,现代类的 backport(ThreeTen for JSR 310;请参阅底部的链接)。
  • On (older) Android use the Android edition of ThreeTen Backport.在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。 It's called ThreeTenABP.它被称为 ThreeTenABP。 And make sure you import the date and time classes from org.threeten.bp with subpackages.并确保使用子包从org.threeten.bp导入日期和时间类。

Links链接

You could use the Java 8 Date API which provides a good set of functionality to convert dates into strings (including timezone support).您可以使用 Java 8 Date API,它提供了一组很好的功能来将日期转换为字符串(包括时区支持)。

An example:一个例子:

    ZonedDateTime dateTime = ZonedDateTime.parse("2017-08-10T00:00:00.000+0000", DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"));
    String newDateStr = dateTime.format(DateTimeFormatter.ofPattern("dd/MM/yyyy Z"));

For more information you can look at:有关更多信息,您可以查看:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM