我尝试使用 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);
}
异常
INFO: Timestamp is invalid formatjava.lang.IllegalArgumentException: Invalid format: "2014-09-23T23:03:11Z" is malformed at "Z"
答案 0 :(得分:8)
我非常怀疑将Z视为字面意思。 char Z有一个含义,即零偏移。 Joda-Time version 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
返回一个格式化程序,它结合了没有毫秒的完整日期和时间, 用'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"
结论:到目前为止,将Z视为文字的其他答案都是错误的,因为输入是在本地时区处理的,而不是偏移UTC + 00:00。使用构造函数或特定类IsoDateTimeFormat
(为了清楚起见,我更倾向于后者)。
关于例外:这是2.0版解决的错误,请参阅release-notes。您应该更好地更新库版本。
在格式模式中允许'Z'和'ZZ'将'Z'解析为'+00:00' [2827359]
答案 1 :(得分:6)
' Z'没有冒号的输出偏移,' ZZ'用冒号输出偏移量,' ZZZ'或更多输出区域ID。
在模式中指定Z
(不带单引号)时,时间戳中的值必须采用格式+HHMM
或-HHMM
作为UTC的数字偏移量。文字字符Z
不是指定格式的有效输入。
示例:
在另一个答案中提到的Levit,如果目标是接受一个文字' Z'在输入时间戳中,不将其视为时区(坏主意),然后可以使用模式中的单引号引用 Z 字符(...'Z'
)。这类似于字面上的' T'将日期组件与时间组件分开。建议不要将输入中的Z
视为文字,因为它具有意义,如果提供,时区是时间戳的重要组成部分。
答案 2 :(得分:-2)
String timestamp = "2014-09-23T23:03:11Z";
DateTime dt = new DateTime(timestamp, DateTimeZone.UTC);
String timestamp = "2014-09-23T23:03:11Z";
String datePattern = "yyyy-MM-dd'T'HH:mm:ss'Z'";
然而,这确实将“零时区偏移”视为文字(因此忽略它),上面的新解决方案考虑了这一点(参见Meno Hochschild的回答更多细节)。