在 java 中验证时间戳格式 yyyy-MM-dd'T'HH:mm:ssZ?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26009841/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 01:41:05  来源:igfitidea点击:

Validating Timestamp format yyyy-MM-dd'T'HH:mm:ssZ in java?

javadatejodatime

提问by Amila Iddamalgoda

I'm trying to do a timestampvalidation using joda time-1.6.2. Please point my error and help me out. Code

我正在尝试使用joda time-1.6.2进行时间戳验证。请指出我的错误并帮助我。 代码

String timestamp = "2014-09-23T23:03:11Z";
String datePattern = "yyyy-MM-dd'T'HH:mm:ssZ";

try {
             DateTimeFormatter dateFormatter = DateTimeFormat.forPattern(datePattern);
             dateFormatter.parseDateTime(timestamp);

        } catch (Exception e) {
            LOG.info("Timestamp is invalid format" + e);
        }

Exception

例外

INFO: Timestamp is invalid formatjava.lang.IllegalArgumentException: Invalid format: "2014-09-23T23:03:11Z" is malformed at "Z"

采纳答案by Levite

In order to not just get a vaild timestamp format, but also have zero offset from UTCuse

为了不仅获得有效的时间戳格式,而且与UTC使用零偏移

String timestamp = "2014-09-23T23:03:11Z";
DateTime dt = new DateTime(timestamp, DateTimeZone.UTC);

Otherwise / Pitfalls

否则/陷阱

When not explicitly specifying the timestamp as UTC, zero offset from local time might be assumed. Also while following might be a valid pattern, it is somewhat misleading.

当未明确指定时间戳为 UTC 时,可能会假设与本地时间的零偏移。此外,虽然遵循可能是一种有效的模式,但它有点误导。

String timestamp = "2014-09-23T23:03:11Z";
String datePattern = "yyyy-MM-dd'T'HH:mm:ss'Z'";

As described by Meno, this treats the zero time zone offset as a literal (therefore ignoring it).

正如 Meno 所描述的,这将零时区偏移量视为文字(因此忽略它)。

Also considers pumping up Meno Hochschild's answer for explaining this in better detail, since I am not allowed to delete mine for now (accepted answer).

还考虑使用 Meno Hochschild 的答案来更详细地解释这一点,因为我现在不允许删除我的(已接受的答案)。

回答by William Price

From the v1.6 API documentation:

来自v1.6 API 文档

'Z' outputs offset without a colon, 'ZZ' outputs the offset with a colon, 'ZZZ' or more outputs the zone id.

'Z' 输出不带冒号的偏移量,'ZZ' 输出带冒号的偏移量,'ZZZ' 或更多输出区域 ID。

When you specify Z(without single quotes) in your pattern, the value in your timestamp must be in the format +HHMMor -HHMMas a numeric offset from UTC. The literal character Zis not valid input for the specified format.

当您Z在模式中指定(不带单引号)时,时间戳中的值必须采用UTC格式+HHMM-HHMM作为数字偏移量。文字字符Z不是指定格式的有效输入。

Examples:

例子:

  • 2014-09-23T23:03:11+0000
  • 2014-09-23T23:03:11-0500
  • 2014-09-23T23:03:11+0430
  • 2014-09-23T23:03:11+0000
  • 2014-09-23T23:03:11-0500
  • 2014-09-23T23:03:11+0430

As Levitmentioned in the other answer, if the goal is to accept a literal 'Z' in the input timestamp without treating it as a time zone(bad idea) then the Zcharacter can be quoted using single quotes in the pattern (...'Z'). That is similar to what was done for the literal 'T' that separates the date components from the time components. Treating Zin the input as a literal is not recommended because it has meaning and, if provided, the time zone is an important component of the timestamp.

正如Levit在另一个答案中提到的,如果目标是在输入时间戳中接受文字 'Z'而不将其视为时区(坏主意),那么可以在模式 ( ) 中使用单引号引用Z字符...'Z'。这类似于对将日期组件与时间组件分开的文字“T”所做的操作。治疗Z在输入不建议字面是因为它具有意义,如果提供的时区的时间戳的重要组成部分。

回答by Meno Hochschild

I am very sceptical about treating Z just as literal. The char Z has a meaning, namely zero offset.The documentation of Joda-Time version 1.6says about this code:

我非常怀疑将 Z 视为字面意思。字符 Z 有一个含义,即零偏移量。Joda-Time 1.6 版的文档说明了这段代码:

String timestamp = "2014-09-23T23:03:11Z";
DateTime dt = 
  ISODateTimeFormat.dateTimeNoMillis().parseDateTime(timestamp).withZone(DateTimeZone.UTC);
System.out.println(dt); // 2014-09-23T23:03:11.000Z

Returns a formatter that combines a full date and time without millis, separated by a 'T' (yyyy-MM-dd'T'HH:mm:ssZZ). The time zone offset is 'Z' for zero, and of the form '±HH:mm' for non-zero.

返回一个格式化程序,它结合了一个完整的日期和时间,没有毫秒,用 'T' 分隔(yyyy-MM-dd'T'HH:mm:ssZZ)。时区偏移为 'Z' 表示零,格式为 '±HH:mm' 表示非零。

Now let's view at following four alternatives in detail (explicitly tested with version 1.6.2):

现在让我们详细查看以下四种替代方案(使用 1.6.2 版本进行了显式测试):

String timestamp = "2014-09-23T23:03:11Z";
DateTimeZone utc = DateTimeZone.UTC;

DateTime dt1 = ISODateTimeFormat.dateTimeNoMillis().parseDateTime(timestamp).withZone(utc);
System.out.println(dt1); // 2014-09-23T23:03:11.000Z (OK)

DateTime dt2 = new DateTime(timestamp, utc);
System.out.println(dt2); // 2014-09-23T23:03:11.000Z (OK)

DateTime dt3 =
  DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss'Z'").parseDateTime(timestamp).withZone(utc);
System.out.println(dt3); //2014-09-23T21:03:11.000Z (WRONG!!!)

DateTime dt4 =
  DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZZ").parseDateTime(timestamp).withZone(utc);
// exception: Invalid format: "2014-09-23T23:03:11Z" is malformed at "Z"

Conclusion:The other answers given so far treating Z as literal are wrong because the input is treated in local timezone, not with offset UTC+00:00. Use either the constructor or the specific class IsoDateTimeFormat(I would prefer latter one for clarity).

结论:到目前为止,将 Z 视为文字的其他答案是错误的,因为输入是在本地时区处理的,而不是偏移 UTC+00:00。使用构造函数或特定类IsoDateTimeFormat(为了清楚起见,我更喜欢后者)。

About the exception:This is a bug solved with version 2.0, see release-notes. You should better update your library version.

关于异常:这是 2.0 版解决的错误,请参阅发行说明。你最好更新你的库版本。

Allow 'Z' and 'ZZ' in format patterns to parse 'Z' as '+00:00' [2827359]

允许格式模式中的“Z”和“ZZ”将“Z”解析为“+00:00” [2827359]