Java 8日期时间格式日期+;抵消
我必须为一个Web服务构造一个Java 8日期时间格式日期+;抵消,java,date,datetime,formatting,java-time,Java,Date,Datetime,Formatting,Java Time,我必须为一个Web服务构造一个xmlgorianicalendar,该Web服务期望的日期格式为yyyy-MM-dd+01:00,其中+之后的值来自时区偏移 到目前为止,我已经尝试过: DateTimeFormatter formatterDateWithOffset = DateTimeFormatter.ofPattern("yyyy-MM-ddZZ"); XMLGregorianCalendar xcal = DatatypeFactory.newInstance() .newX
xmlgorianicalendar
,该Web服务期望的日期格式为yyyy-MM-dd+01:00
,其中+
之后的值来自时区偏移
到目前为止,我已经尝试过:
DateTimeFormatter formatterDateWithOffset = DateTimeFormatter.ofPattern("yyyy-MM-ddZZ");
XMLGregorianCalendar xcal = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(zonedDateTime.format(formatterDateWithOffset));
但这会导致一个illegalargumentexcation
,因为格式化程序生成2017-09-29+0200
是否可以为所需格式定义格式字符串?如果您在
DateTimeFormatter
上查看JavaDoc,您将看到以下内容:
偏移量X和X:根据图案字母的数量设置偏移量的格式。一个字母仅输出小时,如“+01”,除非分钟为非零,在这种情况下,也输出分钟,如“+0130”。两个字母输出小时和分钟,不带冒号,如“+0130”。三个字母输出小时和分钟,带有冒号,如“+01:30”。。。当要输出的偏移量为零时,图案字母“X”(大写)将输出“Z”,而图案字母“X”(小写)将输出“+00”、““+0000”或“+00:00”
因此,DateTimeFormatter formatter datewithoffset=DateTimeFormatter.of模式(“yyyy-MM-ddxxx”)代码>应该可以工作
在我的评论中,我建议使用ZZZZ
,因为JavaDoc也暗示了这一点,但它也会添加GMT
部分(ZZZZZ
似乎有效,尽管JavaDoc声明:“五个字母输出小时、分钟,如果非零,则可选秒,带冒号”).您可以创建传递给它的XMLGregorianCalendar实例,而不是解析:
XMLGregorianCalendar xcal = DatatypeFactory.newInstance().newXMLGregorianCalendar(year, month....)
如上所述,一种替代方法是使用xxx
(或xxx
),如图所示。它们之间的唯一区别是偏移量为零时:XXX
格式为Z
,而XXX
格式为+00:00
:
Pattern Count Equivalent builder methods
------- ----- --------------------------
XXX 3 appendOffset("+HH:MM","Z")
xxx 3 appendOffset("+HH:MM","+00:00")
无论如何,只需选择其中一个(我已经使用zoneDateTime
和ZoneOffset.UTC
对这两个选项进行了测试,并且都有效):
如果您有一个ZoneDateTime
,则更容易将其转换为GregoriaCalendar
,然后将其传递给您的DatatypeFactory
:
ZonedDateTime zonedDateTime = ZonedDateTime.now();
GregorianCalendar cal = GregorianCalendar.from(zonedDateTime);
XMLGregorianCalendar xcal = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
一个棘手的细节是,当使用上面的字符串
模式(仅包含日期)时,结果的时间字段(小时、分钟、秒和毫秒)将设置为零,而转换为GregorianCalendar
将使用ZonedDateTime
中设置的时间
但您可以将时间设置为午夜,然后再将其转换为gregorianalendar
:
// convert to calendar (set the time to 00:00:00.000)
GregorianCalendar cal = GregorianCalendar.from(zonedDateTime.with(LocalTime.MIDNIGHT));
这样,结果将与使用字符串相同。为什么使用ZonedDateTime而不是LocalDateTime?您是否尝试过yyyy-MM-ddZZZZ
?JavaDoc:“一个、两个或三个字母输出小时和分钟,不带冒号,如“+0130”…字母输出完整形式的本地化偏移量”
// convert to calendar (set the time to 00:00:00.000)
GregorianCalendar cal = GregorianCalendar.from(zonedDateTime.with(LocalTime.MIDNIGHT));