java 使用 "Z" 而非“+”格式化时间戳
java format timestamps with "Z" instead of "+"
使用 java 我尝试使用 SimpleDateFormat
使用时区格式化当前日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:SSSZ");
sdf.format(new Date());
这给我结果:
2021-04-28T13:45:52:308+0300
我想使用“Z”而不是“+”获取时区格式
想要的结果:"2021-04-28T13:45:52:308Z03:00"
我将日期输出写在一个文件日志中,该日志将由用 Go 语言编写的 telegraf 插件解析,该插件期望日期和时区格式如下:json_time_format = "2006-01-02T15:04:05Z07:00"
是否有模式允许这样做?
Z 代表“祖鲁时间”或零时差,即 UTC +0:00
如果你不在那个时区,使用它是不正确的。换成Z
怎么知道自己是在子午线之前还是之后呢?给定 Z03:00
,你将其解析为 +03:00
还是 -03:00
?
由于 Z 表示祖鲁时间偏移,因此您不能将其用作格式字符串的一部分,但您当然可以添加 Z
作为硬编码字符
ZonedDateTime now = ZonedDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'Z");
System.out.println(formatter.format(now));
2021-04-29T15:34:17.661Z+0200
然后,如果您不想要“+”,您可以在之后将其删除,但不清楚如何处理“-”,所以我将其排除在答案之外。
如上文所述,在语义上相当 wrong.But 您可以使用一些自定义解析逻辑来实现此目的。
我会假设两件事:
- 日期将不包含具有负差异的时区
- 日期格式不会改变
在任何其他情况下,这都不安全!!
但是给你:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:SSSZ");
String originalDateString = sdf.format(new Date());
String[] parts = originalDateString.split("\+");
StringBuilder sb = new StringBuilder(parts[1]);
sb.insert(2, ':');
parts[1] = sb.toString();
String result = String.join("Z",parts);
System.out.println(result);
这将由此创建:
2021-04-29T14:12:21:376+0000
这个:
2021-04-29T14:12:21:376Z00:00
你误会了。 2006-01-02T15:04:05Z07:00
并不意味着您应该使用 Z
而不是加号(那么您会用什么代替减号呢?)这种指定日期和时间格式的方式近似于固定示例日期的方式和 Mon Jan 2 15:04:05 MST 2006 的时间将被格式化,但这只是一个近似值。特别是当涉及到与 UTC 的偏移量时,当偏移量为零时格式需要 Z
,当偏移量为非零时需要 +hh:mm
或 -hh:mm
。符合 ISO 8601 和 RFC-3339。您会立即看到,仅给出示例日期和时间的正确格式 2006-01-02T15:04:05-07:00
,并不会告诉 reader 偏移量 0 应作为 Z
给出。因此,此特定要求在格式中指定为 Z07:00
。根据 格式化时间或日期 [完整指南](底部的 link),您的特定格式 2006-01-02T15:04:05-0700
表示 ISO 8601 或 RFC-3339。
所以您需要做的就是使用 DateTimeFormat.ISO_OFFSET_DATE_TIME
或 OffsetDateTime.toString()
。
下面是几个例子。
String result = OffsetDateTime.now().toString();
System.out.println(result);
刚才我的时区Java8运行时的输出:
2021-04-29T17:00:55.716+02:00
如果不允许秒的小数部分 — 那么,根据 ISO 8601,它是可选的,所以它应该是,但如果不允许:
String result = OffsetDateTime.now().truncatedTo(ChronoUnit.SECONDS)
.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
2021-04-29T17:00:55+02:00
如果您从遗留代码中获得了老式的 Date
对象,请在格式化之前对其进行转换:
Date oldfashionedDate = new Date();
String result = oldfashionedDate.toInstant()
.atZone(ZoneId.systemDefault())
.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
2021-04-29T17:00:55.739+02:00
链接
使用 java 我尝试使用 SimpleDateFormat
使用时区格式化当前日期SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:SSSZ");
sdf.format(new Date());
这给我结果:
2021-04-28T13:45:52:308+0300
我想使用“Z”而不是“+”获取时区格式
想要的结果:"2021-04-28T13:45:52:308Z03:00"
我将日期输出写在一个文件日志中,该日志将由用 Go 语言编写的 telegraf 插件解析,该插件期望日期和时区格式如下:json_time_format = "2006-01-02T15:04:05Z07:00"
是否有模式允许这样做?
Z 代表“祖鲁时间”或零时差,即 UTC +0:00
如果你不在那个时区,使用它是不正确的。换成Z
怎么知道自己是在子午线之前还是之后呢?给定 Z03:00
,你将其解析为 +03:00
还是 -03:00
?
由于 Z 表示祖鲁时间偏移,因此您不能将其用作格式字符串的一部分,但您当然可以添加 Z
作为硬编码字符
ZonedDateTime now = ZonedDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'Z");
System.out.println(formatter.format(now));
2021-04-29T15:34:17.661Z+0200
然后,如果您不想要“+”,您可以在之后将其删除,但不清楚如何处理“-”,所以我将其排除在答案之外。
如上文所述,在语义上相当 wrong.But 您可以使用一些自定义解析逻辑来实现此目的。 我会假设两件事:
- 日期将不包含具有负差异的时区
- 日期格式不会改变
在任何其他情况下,这都不安全!! 但是给你:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:SSSZ");
String originalDateString = sdf.format(new Date());
String[] parts = originalDateString.split("\+");
StringBuilder sb = new StringBuilder(parts[1]);
sb.insert(2, ':');
parts[1] = sb.toString();
String result = String.join("Z",parts);
System.out.println(result);
这将由此创建: 2021-04-29T14:12:21:376+0000
这个: 2021-04-29T14:12:21:376Z00:00
你误会了。 2006-01-02T15:04:05Z07:00
并不意味着您应该使用 Z
而不是加号(那么您会用什么代替减号呢?)这种指定日期和时间格式的方式近似于固定示例日期的方式和 Mon Jan 2 15:04:05 MST 2006 的时间将被格式化,但这只是一个近似值。特别是当涉及到与 UTC 的偏移量时,当偏移量为零时格式需要 Z
,当偏移量为非零时需要 +hh:mm
或 -hh:mm
。符合 ISO 8601 和 RFC-3339。您会立即看到,仅给出示例日期和时间的正确格式 2006-01-02T15:04:05-07:00
,并不会告诉 reader 偏移量 0 应作为 Z
给出。因此,此特定要求在格式中指定为 Z07:00
。根据 格式化时间或日期 [完整指南](底部的 link),您的特定格式 2006-01-02T15:04:05-0700
表示 ISO 8601 或 RFC-3339。
所以您需要做的就是使用 DateTimeFormat.ISO_OFFSET_DATE_TIME
或 OffsetDateTime.toString()
。
下面是几个例子。
String result = OffsetDateTime.now().toString();
System.out.println(result);
刚才我的时区Java8运行时的输出:
2021-04-29T17:00:55.716+02:00
如果不允许秒的小数部分 — 那么,根据 ISO 8601,它是可选的,所以它应该是,但如果不允许:
String result = OffsetDateTime.now().truncatedTo(ChronoUnit.SECONDS)
.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
2021-04-29T17:00:55+02:00
如果您从遗留代码中获得了老式的 Date
对象,请在格式化之前对其进行转换:
Date oldfashionedDate = new Date();
String result = oldfashionedDate.toInstant()
.atZone(ZoneId.systemDefault())
.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
2021-04-29T17:00:55.739+02:00