我很难弄清楚这个日期格式是什么:2019-02-28T12:17:46.279+0000
。我尝试了不同的日期格式来获得这个结果,但没有任何效果。最近的模式是:yyyy-MM-dd'T'HH:mm:ss.SSSZ
但是这个模式的输出是这样的:2019-02-28T12:17:46.279-0000
(-
是在几秒之后而不是+
)
我得到这个例外:
Caused by: java.lang.IllegalArgumentException: 2019-02-28T12:17:46.279+0000
at org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl$Parser.skip(XMLGregorianCalendarImpl.java:2932)
at org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl$Parser.parse(XMLGregorianCalendarImpl.java:2898)
at org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl.<init>(XMLGregorianCalendarImpl.java:478)
at org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl.newXMLGregorianCalendar(DatatypeFactoryImpl.java:230)
at __redirected.__DatatypeFactory.newXMLGregorianCalendar(__DatatypeFactory.java:132)
at javax.xml.bind.DatatypeConverterImpl.parseDate(DatatypeConverterImpl.java:519)
at javax.xml.bind.DatatypeConverter.parseDate(DatatypeConverter.java:431)
at eu.europa.ec.my.custom.package.model.mapper.XsdDateTimeConverter.unmarshal(XsdDateTimeConverter.java:23)
我的XsdDateTimeConverter
课程看起来像这样:
public class XsdDateTimeConverter {
public static Date unmarshal(String dateTime) {
return DatatypeConverter.parseDate(dateTime).getTime();
}
public static String marshalDate(Date date) {
final Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return DatatypeConverter.printDate(calendar);
}
public static String marshalDateTime(Date dateTime) {
final Calendar calendar = Calendar.getInstance();
calendar.setTime(dateTime);
return DatatypeConverter.printDateTime(calendar);
}
}
我的postgres db中的解析日期如下所示:
move_timestamp timestamp(6) with time zone
2019-02-28 12:17:46.279+00
在我的休息方法中,我像这样使用ObjectMapper
。
MyCustomResponseDto responseDto = customService.getCustomResponseDto(query);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
String strValue = mapper.writeValueAsString(responseDto);
return Response.ok(strValue).build();
我想我真正想要的是这个日期的正确模式是什么。我可以进入这个页面:http://www.sdfonlinetester.info/并输入我的模式(例如yyyy-MM-dd'T'HH:mm:ss.SSSZ
),它会为您提供该模式的实际日期输出。我需要相反的方式。我想输入我的约会,它会给我正确的模式。
OffsetDateTime.parse(
"2019-02-28T12:17:46.279+0000" ,
DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSX" , Locale.ROOT )
)
你正在使用几年前被java.time类取代的糟糕的Calendar
类。
您的输入字符串采用标准的ISO 8601格式,专为人类可读的日期时间值的机器可解析文本表示而设计。这是一件好事。
在解析/生成字符串时,java.time类默认使用ISO 8601格式。
OffsetDateTime
你应该能够简单地用OffsetDateTime
解析。
OffsetDateTime.parse( "2019-02-28T12:17:46.279+0000" )
...但不幸的是,从偏移量(+00:00
)中省略了可选的COLON字符是一个问题。 OffsetDateTime
类有一个小错误,它拒绝解析没有该字符。这个bug被讨论了here和here。
ISO 8601标准允许结肠缺失,但实际上你应该总是包括它。 OffsetDateTime
班并不孤单;我看到其他库在冒号或填充零不存在时会中断。我建议要求您的数据发布者使用完整的ISO 8601格式,包括冒号。
OffsetDateTime
错误的解决方法是明确定义DateTimeFormatter
。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSX" , Locale.ROOT ) ;
然后解析。
String input = "2019-02-28T12:17:46.279+0000" ;
OffsetDateTime odt = OffsetDateTime.parse( input , f ) ;
要以完整标准ISO 8601格式生成文本,只需调用toString
即可。
String output = odt.toString() ;
看到这个code run live at IdeOne.com。
输出:2019-02-28T12:17:46.279Z
最后的Z
表示UTC,即+0000
或+00:00
。发音为“Zulu”。非常常用,比数字偏移更容易读取。
如果您想要与输入相同的输出格式,请使用相同的DateTimeFormatter
。
String output = odt.format( f ) ;
您可以尝试以下代码
SimpleDateFormat format = new SimpleDateFormat(“yyyy-MM-dd'T'HH:mm:ss.SSSZ”,Locale.ENGLISH); String lastmod = format.format(new Date());
为自己省去一大堆麻烦,并以毫秒为单位节省时间。仅在UI中解析和呈现日期。极少数人类安排需要计算机知道小时,天,周,月,年......但是及时保存只是一个“长期”。