【问题标题】:ISO 8601 date-time format combining 'Z' and offset of '+0000'ISO 8601 日期时间格式结合了“Z”和“+0000”的偏移量
【发布时间】:2016-06-21 18:03:57
【问题描述】:

我正在使用 ISO 8601 的日期时间格式。我有这种模式:

"yyyy-MM-dd'T'HH:mm:ssZZ'Z'"

输出是:

"2015-11-17T00:00:00+0000Z".

我的问题是输出是否正常,是否可以在日期 +0000 和 Z 中考虑到两者具有相同的含义时区偏移量/ID。提前感谢您的澄清=)

【问题讨论】:

  • @BasilBourque 我认为需要澄清,很明显,它询问该日期格式是否可以 "2015-11-17T00:00:00+0000Z" =)

标签: time datetime-format iso8601 timezone-offset


【解决方案1】:

不行,不行

不,Z offset-from-UTC,因此它不应与+00:00+0000 的数字偏移量冗余组合。

ISO 8601

虽然我无法访问ISO 8601 规范的付费副本,但Wikipedia page 明确指出Z 必须遵循时间:

…在时间之后直接添加一个 Z,不带空格。

IETF RFC 3339

免费提供的RFC 3339(ISO 8601 配置文件)将Z 定义为附加到时间:

一个后缀……应用于时间……

RFC 还通过正式的ABNF notation 声明我们应该使用Z 或数字。在 ABNF 中,斜线 (SOLIDUS) 表示“或”(唯一的“或”),而方括号对表示“可选”。

time-numoffset = ("+" / "-") time-hour [[":"] time-minute]

time-zone = "Z" / time-numoffset

此外,规范的section 5.4 特别推荐反对包括冗余信息。

Java

Java 内置的现代 java.time 类在解析/生成字符串时默认使用标准的ISO 8601 格式。见Oracle Tutorial

解析文本输入

Z:

Instant instant = Instant.parse( "2019-01-23T12:34:56.123456789Z" ) ;

+00:00:

OffsetDateTime odt = OffsetDateTime.parse( "2019-01-23T12:34:56.123456789+00:00" ) ;

生成文本输出

要使用Z 创建字符串,只需调用Instant::toString

String output = Instant.now().toString() ;  // Capture the current moment in UTC, then generate text representing that value in standard ISO 8601 using the `Z` offset-indicator.

2019-05-22T21:00:52.214709Z

要使用00:00 创建字符串,请调用OffsetDateTime::format。使用 DateTimeFormatter 和您定义的格式模式生成文本。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSxxx" ) ;
String output = OffsetDateTime.now( ZoneOffset.UTC ).format( f ) ;

2019-05-22T21:00:52.319076+00:00

截断

您可能想要截断任何微秒或纳秒。

Instant
.now()
.truncatedTo( ChronoUnit.MILLIS )
.toString()

2019-05-22T21:11:28.970Z

……和……

OffsetDateTime
.now( ZoneOffset.UTC )
.truncatedTo( ChronoUnit.MILLIS )
.format( 
    DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSxxx" )
)

2019-05-22T21:11:29.078+00:00

看到这个code running live at IdeOne.com

【讨论】:

  • 在 Java 中:final String DATE_FORMAT_ISO_8601 = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
  • @SomeoneSomewhere 不,不要将Z 埋在一对单引号内。这会将Z 变成字符串文字,仅仅是装饰,而不是有意义的模式代码。
  • 我目前正在从事一个加密货币项目,API 规范要求末尾是“Z”,而不是“+0000”。 docs.pro.coinbase.com/?javascript#time
  • @SomeoneSomewhere 很好,但这不是定义损坏格式模式的理由。格式化模式中的Z 应该永远在单引号内。我将编辑答案以显示让Z 出现的简单方法:Instant.now().toString()。您可能想要截断任何微秒/纳秒:Instant.now().truncatedTo( ChronoUnit.MILLIS ).toString()
猜你喜欢
  • 2014-04-15
  • 2019-09-07
  • 2013-11-27
  • 1970-01-01
  • 2016-03-06
  • 1970-01-01
  • 1970-01-01
  • 2013-05-22
  • 2021-10-19
相关资源
最近更新 更多