我对Java8的日期格式/解析功能有点失望。我想找到Jackson的配置 DateTimeFormatter
解析 "2018-02-13T10:20:12.120+0000"
字符串到任何Java8日期,但没有找到它。
这是 java.util.Date
工作正常的示例:
Date date = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSZZZ")
.parse("2018-02-13T10:20:12.120+0000");
新的日期时间api不能使用相同的格式
ZonedDateTime dateTime = ZonedDateTime.parse("2018-02-13T10:20:12.120+0000",
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'hh:mm:ss.SSSZZZ"));
我们应该能够格式化/解析任何适合fe ui应用程序的格式的日期。也许我误解了什么,但我想 java.util.Date
提供更大的格式灵活性和更易于使用。
3条答案
按热度按时间bf1o4zei1#
简:不是虫子,只是你的模式不对。
请使用类型
OffsetDateTime
它是专门为时区偏移设计的,并以这种方式使用模式:具体问题:
a) 12小时制与24小时制
“h”表示12小时制的上午/下午的时间,但根据iso-8601的要求,您显然需要“h”表示24小时制。
b) 零偏移形式
如果您想解析零偏移量,例如“+0000”而不是“z”(如iso论文中所述),则不应使用模式符号“x”,而应使用“zzz”。引用模式语法:
偏移量z:根据图案字母的数量设置偏移量的格式。一个、两个或三个字母输出小时和分钟,不带冒号,例如“+0130”。当偏移量为零时,输出将为“+0000”。
c) 您的输入与iso-8601不兼容,因此java中没有bug
您认为“2018-02-13t10:20:12.120+0000”应为有效iso的假设是错误的,因为您混合了基本格式(在偏移部分)和iso文件中明确禁止的扩展格式(见第4.3.2节(示例部分)和第4.3.3d节)。引用iso-8601:
[…]表达式应完全采用基本格式,在这种情况下,使用所需表达式所需的最小分隔符数,或完全采用扩展格式[…]
b的陈述。波克
java.time
有一个bug是基于对iso兼容性的错误期望。比如说ISO_OFFSET_DATE_TIME
仅描述对扩展iso格式的支持。另请参阅相关的jdk问题。并不是所有的iso-8601变体都被直接支持,因此以正确的方式构建基于模式的解析器是可以的。bxpogfeg2#
如果偏移量+0000,请尝试此操作
23c0lvtd3#
热释光;博士
在修复错误之前:
修复错误时:
详细信息
你使用了错误的类。
避免麻烦的旧遗留类,例如
Date
,Calendar
,和SimpleDateFormat
. 现在被java.time类取代。这个
ZonedDateTime
您使用的类很好,它是java.time的一部分。但它是为一个完整的时区设计的。您的输入字符串与utc之间只有一个偏移量。相比之下,完整时区是一个区域在过去、现在和将来的不同时间点的有效偏移量的集合。例如,在北美大部分地区,随着夏令时(dst)的到来,偏移量每年变化两次,在 Spring ,当我们将时钟向前移动一小时时,偏移量会变小,而在秋季,当我们将时钟向后移动一小时时,偏移量会恢复到更长的值。偏移日期时间
对于仅偏移量而不是时区,请使用
OffsetDateTime
班级。您的输入字符串符合iso 8601标准。在解析/生成字符串时,java.time类默认使用标准格式。所以不需要指定格式化模式。
好吧,那应该管用的。不幸的是,java8中存在一个bug(至少在java8 update121中是这样),该类无法解析在小时和分钟之间省略冒号的偏移量。所以虫子咬人了
+0000
但不是+00:00
. 因此,在得到修复之前,您可以从两种解决方法中选择:(a)黑客,操作输入字符串,或(b)定义显式格式模式。黑客:操纵输入字符串以插入冒号。
日期时间格式
更健壮的解决方法是在
DateTimeFormatter
对象。odt.tostring():2018-02-13t10:20:12.120z
顺便说一句,这里有一个提示:我发现在许多协议和库中,如果偏移量总是有冒号,总是同时有小时和分钟(即使分钟是零),并且总是使用填充零,那么您的生活会更轻松(
-05:00
而不是-5
).日期时间格式生成器
对于更灵活的格式化程序,通过
DateTimeFormatterBuilder
,在重复的问题上看到这个极好的答案。瞬间
如果您想使用总是以utc为单位的值(您应该这样做),请提取
Instant
对象。分区日期
如果你想通过某个地区的挂钟时间来观察这一时刻,请使用时区。
请在ideone.com上查看此代码的实时运行。
所有这些都在许多问题的许多答案中被多次提及。请在投递前彻底搜索堆栈溢出。你可能会发现几十个,甚至几百个例子。
关于java.time
java.time框架内置于Java8及更高版本中。这些类取代了旧的遗留日期时间类,例如
java.util.Date
,Calendar
, &SimpleDateFormat
.现在处于维护模式的joda time项目建议迁移到java.time类。
要了解更多信息,请参阅oracle教程。和搜索堆栈溢出的许多例子和解释。规格为jsr 310。
您可以直接与数据库交换java.time对象。使用符合jdbc 4.2或更高版本的jdbc驱动程序。不需要线,不需要线
java.sql.*
班级。从哪里获得java.time类?
java se 8、java se 9、java se 10及更高版本
内置的。
标准javaapi的一部分,带有一个捆绑的实现。
Java9添加了一些次要的特性和修复。
java se 6和java se 7
大部分java.time功能都是通过310个后端口后端口移植到Java6和Java7的。
安卓
android包java.time类的更高版本实现。
对于早期的android(<26),threetenabp项目采用了threeten backport(如上所述)。了解如何使用threetenabp…。
threeten额外的项目用额外的类扩展了java.time。这个项目是java.time将来可能添加的一个试验场。您可以在这里找到一些有用的类,例如
Interval
,YearWeek
,YearQuarter
,等等。