java 将 UTC 转换为本地时区时出现日期解析异常

java date parse exception while conveting UTC to local time zone

我得到一个具有以下格式的 UTC 日期,如何将这个 UTC 日期转换为我的本地时区?

我的输入日期是 2015-03-17 06:00:00 +0000 我尝试了以下编码,它给出了解析异常。

我的代码:

DateFormat utcFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss 'Z'");
utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = utcFormat.parse("2015-03-17 06:00:00 +0000"); // java.text.DateFormat.parse(Unknown Source)
utcFormat.setTimeZone(TimeZone.getDefault());
System.out.println(utcFormat.format(date));

我认为这是由于日期模式中的引号引起的。

试试这个...

DateFormat utcFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss ZZZZ");

移除 ' 周围的 Z 并重试。

你的代码有两个错误。

  1. 正如其他人已经提到的,您的模式中有额外的 ' Z
  2. 您将模式指定为 dd-MM-yyyy,但尝试将日期解析为 yyyy-MM-dd

正确版本:

DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = utcFormat.parse("2015-03-17 06:00:00 +0000");
utcFormat.setTimeZone(TimeZone.getDefault());
System.out.println(utcFormat.format(date));

此功能已经过测试,可与任何 java.util.Date 对象完美配合。

private SimpleDateFormat getDateFormat() {
    SimpleDateFormat dateFormat = (SimpleDateFormat) SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.DEFAULT, Locale.getDefault());
    String pattern = dateFormat.toLocalizedPattern();
    pattern = pattern.trim();
    dateFormat.applyLocalizedPattern(pattern);
    return dateFormat;
}

//And here is the usage
SimpleDateFormat sdf = getDateFormat();
sdf.format(new Date());

我重构了来自以下网站的代码,您可能会发现这些代码对于格式化为不同类型的 java.util.Date 对象非常有用:

https://www.programcreek.com/java-api-examples/index.php?class=java.text.SimpleDateFormat&method=applyLocalizedPattern

希望对您有所帮助

我想贡献现代答案。问题中使用的 DateSimpleDateFormat 类 早就过时了,今天我们好多了。我推荐现代 Java 日期和时间 API 称为 JSR-310 或 java.time:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss Z");
    System.out.println(ZonedDateTime.parse("2015-03-17 06:00:00 +0000", formatter)
            .withZoneSameInstant(ZoneId.systemDefault())
            .format(formatter));

在我的 Europe/Copenhagen 时区的计算机上打印

2015-03-17 07:00:00 +0100

不过,使用 ZoneId.systemDefault() 很脆弱,因为 JVM 上的任何程序 运行 都可以更改其默认时区,从而改变上述代码段的行为。如果可以,最好使用 region/city 格式的时区 ID,例如 ZoneId.of("Asia/Tomsk")ZoneId.of("America/Argentina/Rio_Gallegos").

问题:我的 Java 版本可以使用现代 API 吗?

如果至少使用 Java 6,则可以。

  • 在 Java 8 及更高版本中内置了新的 API。
  • 在 Java 6 和 7 get the ThreeTen Backport 中,新 类 的向后移植(即 JSR-310 的 ThreeTen,其中首次定义了现代 API ).
  • 在 Android 上,使用 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP,我认为 中有一个很好的解释。