繁体   English   中英

了解具体的UTC时间格式YYYY-MM-DDTHH:MM:SS.SSSZ

[英]Understanding specific UTC time format YYYY-MM-DDTHH:MM:SS.SSSZ

我有两个相关的问题。

假设在 BST 中运行的程序以 UTC YYYY-MM-DDTHH:MM:SS.SSSZ 格式生成当前时间的日期时间值

还假设伦敦的当前时间是 2016-06-01 12:33:54

  1. 如果程序给出的当前时间是 2016-06-01T11:33:54.000Z ,是不是程序出错了?

  2. BST 的夏季偏移如何以 YYYY-MM-DDTHH:MM:SS.SSSZ 的相应时间格式记录

我假设 YYYY-MM-DDTHH:MM:SS+0001 我正确吗?

首先请阅读iso8601信息。 处理不同时区(例如服务器时区和客户端时区)的时间变得越来越普遍,并且该标准非常有用。

特别是请在此处阅读 UTC 或“祖鲁”时间。

  1. 程序是正确的,因为伦敦时间比夏季的“UTC”时间提前一小时

  2. 尾随的“Z”是 UTC(祖鲁语)的缩写。 你也可以写“+00:00”而不是“Z”。 SS.SSS 指的是秒和毫秒 - 与时区无关。 在 devnull 的评论中,他向您展示了如何为夏季应用偏移量。

编辑

评论中有一些关于iso8601时区是否包含时区以及时区是否会被打印出来的讨论。

这完全取决于日期/时间实现。 如果我们使用SimpleDateFormat则支持时区并将被打印。

这是一个代码示例来说明

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(formatter.format(new Date()));
formatter.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println(formatter.format(new Date()));

输出

2016-06-02T12:53:14.924Z
2016-06-02T13:53:14.925+01:00

自然,如果您使用不同的日期/时间库,例如joda-time ,那么实现细节将有所不同。

编辑:正如@DerrylThomas 指出的, SimpleDateFormat明智地使用小写y多年 - 除非它打算使用周年 - 在另一个类似问题的答案中详细解释了https://stackoverflow.com/a/56911450 .

如果程序给出的当前时间是 2016-06-01T11:33:54.000Z ,是不是程序出错了?

格式正确且符合ISO 8601,但不代表欧洲/伦敦时间。 2016年的伦敦,夏令时从3 月 27 日星期日凌晨 1 点开始,到 10 月 30 日星期日凌晨 2 点结束,因此在此期间欧洲/伦敦的日期时间表示应具有时区偏移+01:00小时。 末尾的Z指定Zulu时间,即 UTC 时间,因此时区偏移为+00:00小时。 欧洲/伦敦的同一时刻可以表示为2016-06-01T12:33:54+01:00

时间

java.util日期时间 API 及其格式化 API SimpleDateFormat已过时且容易出错。 建议完全停止使用它们并切换到java.time现代日期时间 API *

甚至Joda-Time也不应该再使用了。 请注意Joda-Time 主页上的以下说明

Joda-Time 是 Java SE 8 之前的 Java 事实标准日期和时间库。现在要求用户迁移到 java.time (JSR-310)。

java.time API 基于ISO 8601和日期时间字符串, 2016-06-01T11:33:54.000Z可以解析为java.time.ZonedDateTimejava.time.OffsetDateTime而无需日期时间解析/格式化类型。

演示:

import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        ZonedDateTime zdt = ZonedDateTime.parse("2016-06-01T11:33:54.000Z");
        System.out.println(zdt);

        ZoneId zoneId = ZoneId.of("Europe/London");
        ZonedDateTime zdtInLondon = zdt.withZoneSameInstant(zoneId);
        System.out.println(zdtInLondon);
    }
}

输出:

2016-06-01T11:33:54Z
2016-06-01T12:33:54+01:00[Europe/London]

如何处理夏令时 (DST)?

如前所述,日期时间字符串2016-06-01T11:33:54.000Z也可以解析为java.time.OffsetDateTime而无需日期时间解析/格式化类型。 然而, OffsetDateTime被设计为处理固定的时区偏移,ZonedDateTime被设计为处理时区,因此它会自动处理 DST。 您可以将转换ZonedDateTimeOffsetDateTime使用ZonedDateTime#toOffsetDateTime如果需要的话。

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS z", Locale.ENGLISH);

        String strDateTime = "2016-03-01T11:33:54.000 Europe/London";
        ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
        System.out.println(zdt);

        strDateTime = "2016-06-01T11:33:54.000 Europe/London";
        zdt = ZonedDateTime.parse(strDateTime, dtf);
        System.out.println(zdt);
    }
}

输出:

2016-03-01T11:33:54Z[Europe/London]
2016-06-01T11:33:54+01:00[Europe/London]

请注意时区偏移如何自动从Z更改为01:00以反映 DST 更改。 另一方面,

import java.time.OffsetDateTime;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2016-03-01T11:33:54.000+01:00";
        OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
        System.out.println(odt);

        strDateTime = "2016-06-01T11:33:54.000+01:00";
        odt = OffsetDateTime.parse(strDateTime);
        System.out.println(odt);
    }
}

输出:

2016-03-01T11:33:54+01:00
2016-06-01T11:33:54+01:00

在这种情况下,您不谈论时区(例如欧洲/伦敦); 相反,您谈论的是+01:00小时的固定时区偏移。

Trail: Date Time 中了解有关现代日期时间 API 的更多信息。


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

暂无
暂无

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

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