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

Ami*_*oda 6 java date jodatime

我正在尝试使用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);
        }
Run Code Online (Sandbox Code Playgroud)

例外

INFO: Timestamp is invalid formatjava.lang.IllegalArgumentException: Invalid format: "2014-09-23T23:03:11Z" is malformed at "Z"
Run Code Online (Sandbox Code Playgroud)

Men*_*ild 8

我非常怀疑将Z视为字面意思.char 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
Run Code Online (Sandbox Code Playgroud)

返回一个格式化程序,它将完整的日期和时间组合在一起,没有毫秒,用'T'分隔(yyyy-MM-dd'T'HH:mm:ssZZ).对于零,时区偏移为'Z',对于非零,时区偏移为'±HH:mm'.

现在让我们详细了解以下四个备选方案(使用版本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"
Run Code Online (Sandbox Code Playgroud)

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

关于异常:这是使用2.0版解决的错误,请参阅发行说明.您应该更好地更新库版本.

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


Wil*_*ice 6

v1.6 API文档:

'Z'输出偏移而没有冒号,'ZZ'输出带冒号的偏移量,'ZZZ'或更多输出区域id.

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

例子:

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

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


Lev*_*ite -3

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

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

否则/陷阱

当未明确将时间戳指定为 UTC 时,可能会假定距本地时间的偏移量为零。此外,虽然以下可能是有效的模式,但它有些误导性。

String timestamp = "2014-09-23T23:03:11Z";
String datePattern = "yyyy-MM-dd'T'HH:mm:ss'Z'";
Run Code Online (Sandbox Code Playgroud)

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

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

  • **不正确的答案。有关详细信息,请参阅 [Meno Hochschild 的回答](http://stackoverflow.com/a/26014153/642706)。 (2认同)