tl;博士
直到错误被修复:
OffsetDateTime.parse(
"2018-02-13T10:20:12.120+0000" ,
DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSX" )
)
bug 修复后:
OffsetDateTime.parse( "2018-02-13T10:20:12.120+0000" )
详情
你使用了错误的类。
避免使用麻烦的旧遗留类,例如Date、Calendar 和SimpleDateFormat。现在被java.time 类所取代。
您使用的ZonedDateTime 类很好,它是java.time 的一部分。但它适用于一个完整的时区。您的输入字符串只有一个offset-from-UTC。相比之下,完整时区是在过去、现在和未来的不同时间点对区域有效的偏移量的集合。例如,在北美大部分地区采用夏令时 (DST) 时,偏移量每年两次变化,在春季我们将时钟向前移动一个小时时会变小,并在秋季将时钟向后移动一个小时时恢复到更长的值。小时。
OffsetDateTime
仅对于偏移量而不是时区,请使用 OffsetDateTime 类。
您的输入字符串符合ISO 8601 标准。 java.time 类在解析/生成字符串时默认使用标准格式。所以不需要指定格式模式。
OffsetDateTime odt = OffsetDateTime.parse( "2018-02-13T10:20:12.120+0000" );
嗯,那应该起作用了。不幸的是,Java 8 中存在一个错误(至少在 Java 8 更新 121 之前),该类无法解析在小时和分钟之间省略冒号的偏移量。所以这个错误会咬+0000 而不是+00:00。因此,在修复到来之前,您可以选择两种解决方法:(a) hack,操作输入字符串,或 (b) 定义显式格式模式。
技巧:操作输入字符串以插入冒号。
String input = "2018-02-13T10:20:12.120+0000".replace( "+0000" , "+00:00" );
OffsetDateTime odt = OffsetDateTime.parse( input );
DateTimeFormatter
更可靠的解决方法是在 DateTimeFormatter 对象中定义和传递格式模式。
String input = "2018-02-13T10:20:12.120+0000" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSX" );
OffsetDateTime odt = OffsetDateTime.parse( input , f );
odt.toString(): 2018-02-13T10:20:12.120Z
顺便说一下,这里有一个提示:我发现对于许多协议和库,如果偏移量总是有冒号,总是有小时和分钟(即使分钟为零),你的生活会更轻松(即使分钟为零)使用填充零(-05:00 而不是-5)。
DateTimeFormatterBuilder
有关通过DateTimeFormatterBuilder 创建的更灵活的格式化程序,请参阅this excellent Answer 的重复问题。
Instant
如果您想使用始终采用 UTC 的值(并且您应该),请提取一个 Instant 对象。
Instant instant = odt.toInstant();
ZonedDateTime
如果您想通过某个地区的wall-clock time 的镜头观看那一刻,请应用时区。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = odt.atZoneSameInstant( z );
看到这个code run live at IdeOne.com。
许多问题的许多答案中已多次涵盖所有这些内容。请在发布前彻底搜索 Stack Overflow。您可能会发现数十个(如果不是数百个)示例。
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。