为什么字符串到日期并返回字符串导致两个不同的字符串?

时间:2016-06-14 15:12:10

标签: java date-format simpledateformat datetime-format

我的输入字符串是:

"2016-06-13T14:20:09.866Z"

我的输出字符串是:

"2016-06-13T10:20:09.866-04"

为什么它们不同,如​​何以与输入相同的格式输出?

我从字符串转换为日期:

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.ENGLISH);
dateFormat.parse((String) date));

在单元测试中,我将解析后的日期转换回字符串:

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.ENGLISH);
dateFormat.format(date);

2 个答案:

答案 0 :(得分:3)

这两个日期是相同的 - 只有格式不同(一个是UTC时间下午2点,另一个是上午10点,偏移量为-4小时= UTC时间下午2点)。

所以我想你想要的是在UTC时区也有第二个字符串。在这种情况下,您只需设置第二个DateFormat的时区:

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.ENGLISH);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

答案 1 :(得分:2)

<块引用>

为什么它们不同,我怎样才能让它以相同的格式输出 作为输入?

它们不仅代表同一时刻,而且格式相同,ISO 8601

2016-06-13T14:20:09.866Z 表示 UTC 中的日期时间。其中的 Z 是零时区偏移的 timezone designator。它代表祖鲁语并指定 Etc/UTC 时区(时区偏移为 +00:00 小时)。

2016-06-13T10:20:09.866-042016-06-13T10:20:09.866-04:00 表示时区偏移为 -04:00 小时的日期时间,即这一时刻在 UTC 中可以表示为 2016-06-13T14:20:09.866+00:002016-06-13T14:20:09.866Z .

请注意,旧的日期时间 API(java.util 日期时间类型及其格式类型 SimpleDateFormat)已过时且容易出错。建议完全停止使用,改用java.timemodern date-time API*

使用现代 API 的演示:

import java.time.OffsetDateTime;
import java.time.ZoneOffset;

public class Main {
    public static void main(String[] args) {
        OffsetDateTime odtWithMinusFourHoursOffset = OffsetDateTime.parse("2016-06-13T10:20:09.866-04");
        System.out.println(odtWithMinusFourHoursOffset);

        OffsetDateTime odtWithSameMomentInUtc = odtWithMinusFourHoursOffset.withOffsetSameInstant(ZoneOffset.UTC);
        System.out.println(odtWithSameMomentInUtc);
    }
}

输出:

2016-06-13T10:20:09.866-04:00
2016-06-13T14:20:09.866Z

您有没有注意到,我们在这里没有使用 DateTimeFormatter

现代日期时间 API 基于 ISO 8601,只要日期时间字符串符合 ISO 8601 标准,就不需要明确使用 DateTimeFormatter 对象。

modern date-time API 中了解有关 Trail: Date Time* 的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project