java.time
Joda-Time开发团队建议迁移至java.time类:
Joda-Time是Java SE 8之前的事实标准日期和时间库。现在要求用户迁移到java.time(JSR-310)。
这个java.time框架内置于Java 8及更高版本中。这些类取代了旧的麻烦日期时间类,如java.util.Date
以及广受欢迎的第三方Joda-Time库。请参见Oracle教程。大部分java.time功能已经在ThreeTen-Backport中向Java 6和7进行了后移植,并在ThreeTenABP中进一步适用于Android。
OffsetDateTime
OffsetDateTime
类表示带有指定UTC偏移量的时间线上的一个瞬间。该偏移量由ZoneOffset
类表示。
LocalDateTime
如果您的输入字符串缺少任何偏移量或时区信息,则被视为“本地”日期时间。这意味着它不是时间线上的特定时刻,而是关于可能时刻的粗略概念。在应用偏移量或时区之前没有实际意义。
LocalDateTime
类处理此类值。
ISO 8601
您的输入字符串恰好符合 ISO 8601 日期时间文本格式标准。
当解析/生成表示日期时间值的字符串时,java.time类默认使用这些标准格式。因此,您可以直接解析输入字符串而无需定义格式模式。
示例代码
这里的策略是尝试解析输入字符串是否包含偏移量。如果没有,则抛出异常(DateTimeParseException
)。在这种情况下,我们再次尝试解析,但作为 LocalDateTime
值。如果第二次尝试引发解析异常,则输入完全不符合预期。
一些编码原则主义者可能会反对使用嵌套异常测试。虽然我理解他们的担忧,因为这种方法可能被滥用,但在这种特定类型的情况下,我认为嵌套异常测试是可以接受、逻辑清晰的。
String input = "2016-07-11T16:50:22.00"; // "2016-07-11T16:50:22.00+05:00";
Boolean hasOffset = null;
try {
OffsetDateTime odt = OffsetDateTime.parse ( input );
hasOffset = Boolean.TRUE;
ZoneOffset offset = odt.getOffset ();
System.out.println ( "input: " + input + " | hasOffset: " + hasOffset + " | odt: " + odt + " | offset: " + offset );
} catch ( java.time.format.DateTimeParseException e1 ) {
// Perhaps input lacks offset-from-UTC. Try parsing as a local date-time.
try {
LocalDateTime ldt = LocalDateTime.parse ( input );
hasOffset = Boolean.FALSE;
System.out.println ( "input: " + input + " | hasOffset: " + hasOffset + " | ldt: " + ldt );
} catch ( java.time.format.DateTimeParseException e2 ) {
System.out.println ( "ERROR - Unexpected format in the input string" ); // FIXME: Handle format exception.
}
}
当使用
2016-07-11T16:50:22.00+05:00
运行时。
输入:2016-07-11T16:50:22.00+05:00 | hasOffset: true | odt: 2016-07-11T16:50:22+05:00 | offset: +05:00
当使用
2016-07-11T16:50:22.00
运行时。
输入:2016-07-11T16:50:22.00 | hasOffset: false | ldt: 2016-07-11T16:50:22
长度测试
当然,您可以始终测试输入字符串的长度。根据您的示例输入,具有偏移量的输入将比没有偏移量的输入更长。如果您有多种输入,则此类长度测试可能不稳定或容易出错。
Z
,-05
,-05:00
。顺便说一下,America/Chicago
的偏移量是负数而不是正数。你的输出/代码有些可疑。 - Michael-O