了解特定的 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
如果程序给出的当前时间是2016-06-01T11:33:54.000Z,是不是程序出错了?
如何在 YYYY-MM-DDTHH:MM:SS.SSSZ
的相应时间格式中记录 BST 的夏季偏移量
我假设 YYYY-MM-DDTHH:MM:SS+0001 我是对的吗?
首先请阅读iso8601资料。处理不同时区(例如服务器时区和客户端时区)的时间变得越来越普遍,这个标准真的很有用。
请特别阅读 UTC 或“祖鲁”时间 here。
程序是正确的,因为夏季伦敦时间比“UTC”时间早一小时
结尾的 'Z' 是 UTC(祖鲁语)的简称。您也可以写“+00:00”而不是 'Z'。 SS.SSS 指秒和毫秒 - 与时区无关。在 devnull 的评论中,他向您展示了如何为夏季应用偏移量。
编辑:
评论里有人讨论了iso8601时区是否包含timezone,timezone是否会打印出来。
这完全取决于 date/time 实现。如果我们使用 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
当然,如果您使用不同的 date/time 库,例如 joda-time
,那么实现细节会有所不同。
编辑: 正如@DerrylThomas 指出的 SimpleDateFormat
多年来使用小写字母 y 是明智的——除非它是有意的使用星期年 - 在另一个类似问题的答案中详细解释 。
if the current time given by the program is 2016-06-01T11:33:54.000Z ,
is the program wrong?
格式正确,符合ISO 8601 but it does not represent Europe/London time. In London, in 2016,夏令时开始于3月27日,星期日,1:00上午,结束于10 月 30 日,星期日,2:00 上午 ,因此在此期间 Europe/London 的日期时间表示应具有 +01:00
小时的时区偏移。最后的 Z
指定 Zulu
时间,这是 UTC 时间,因此时区偏移量为 +00:00
小时。 Europe/London 的同一时刻可以表示为 2016-06-01T12:33:54+01:00
.
java.time
java.util
日期时间 API 及其格式 API、SimpleDateFormat
已过时且容易出错。建议完全停止使用,改用java.time
,modern date-time API* .
甚至 Joda-Time 也不应该再使用了。请注意 Home Page of Joda-Time
处的以下注释
Joda-Time is the de facto standard date and time library for Java
prior to Java SE 8. Users are now asked to migrate to java.time
(JSR-310).
java.time
API基于ISO 8601
和日期时间字符串,2016-06-01T11:33:54.000Z
可以解析为java.time.ZonedDateTime
和java.time.OffsetDateTime
不需要日期时间 parsing/formatting 类型。
演示:
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
而无需日期时间 parsing/formatting 类型。但是,OffsetDateTime
旨在处理固定的 时区偏移量,而 ZonedDateTime
旨在处理timezone 因此它会自动处理 DST。如果需要,您可以使用 ZonedDateTime#toOffsetDateTime
将 ZonedDateTime
转换为 OffsetDateTime
。
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
在这种情况下,您不谈论时区(例如Europe/London);相反,您谈论的是 +01:00
小时的固定时区偏移量。
了解有关现代日期时间 API 的更多信息
* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and 。
我有两个相关问题。
假设 BST 中的程序 运行 以 UTC YYYY-MM-DDTHH:MM:SS.SSSZ 格式生成当前时间的日期时间值
同时假设伦敦的当前时间是 2016-06-01 12:33:54
如果程序给出的当前时间是2016-06-01T11:33:54.000Z,是不是程序出错了?
如何在 YYYY-MM-DDTHH:MM:SS.SSSZ
的相应时间格式中记录 BST 的夏季偏移量
我假设 YYYY-MM-DDTHH:MM:SS+0001 我是对的吗?
首先请阅读iso8601资料。处理不同时区(例如服务器时区和客户端时区)的时间变得越来越普遍,这个标准真的很有用。
请特别阅读 UTC 或“祖鲁”时间 here。
程序是正确的,因为夏季伦敦时间比“UTC”时间早一小时
结尾的 'Z' 是 UTC(祖鲁语)的简称。您也可以写“+00:00”而不是 'Z'。 SS.SSS 指秒和毫秒 - 与时区无关。在 devnull 的评论中,他向您展示了如何为夏季应用偏移量。
编辑:
评论里有人讨论了iso8601时区是否包含timezone,timezone是否会打印出来。
这完全取决于 date/time 实现。如果我们使用 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
当然,如果您使用不同的 date/time 库,例如 joda-time
,那么实现细节会有所不同。
编辑: 正如@DerrylThomas 指出的 SimpleDateFormat
多年来使用小写字母 y 是明智的——除非它是有意的使用星期年 - 在另一个类似问题的答案中详细解释
if the current time given by the program is 2016-06-01T11:33:54.000Z , is the program wrong?
格式正确,符合ISO 8601 but it does not represent Europe/London time. In London, in 2016,夏令时开始于3月27日,星期日,1:00上午,结束于10 月 30 日,星期日,2:00 上午 ,因此在此期间 Europe/London 的日期时间表示应具有 +01:00
小时的时区偏移。最后的 Z
指定 Zulu
时间,这是 UTC 时间,因此时区偏移量为 +00:00
小时。 Europe/London 的同一时刻可以表示为 2016-06-01T12:33:54+01:00
.
java.time
java.util
日期时间 API 及其格式 API、SimpleDateFormat
已过时且容易出错。建议完全停止使用,改用java.time
,modern date-time API* .
甚至 Joda-Time 也不应该再使用了。请注意 Home Page of Joda-Time
处的以下注释Joda-Time is the de facto standard date and time library for Java prior to Java SE 8. Users are now asked to migrate to java.time (JSR-310).
java.time
API基于ISO 8601
和日期时间字符串,2016-06-01T11:33:54.000Z
可以解析为java.time.ZonedDateTime
和java.time.OffsetDateTime
不需要日期时间 parsing/formatting 类型。
演示:
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
而无需日期时间 parsing/formatting 类型。但是,OffsetDateTime
旨在处理固定的 时区偏移量,而 ZonedDateTime
旨在处理timezone 因此它会自动处理 DST。如果需要,您可以使用 ZonedDateTime#toOffsetDateTime
将 ZonedDateTime
转换为 OffsetDateTime
。
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
在这种情况下,您不谈论时区(例如Europe/London);相反,您谈论的是 +01:00
小时的固定时区偏移量。
* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and