ecb*_*die 17 java datetime jodatime jackson deserialization
这个问题是关于反序列化到乔达时间 日期时间使用杰克逊的数据类型-乔达模块的杰克逊.是否有一个默认时区,日期字符串将被反序列化?如果是这样,它是什么?是UTC吗?
我需要问这个,因为杰克逊的文档并不是特定的Joda-Time DateTime.我在本文(http://wiki.fasterxml.com/JacksonFAQDateHandling)中发现,杰克逊将GMT作为反序列化为java.util.Date或的默认时区java.util.Calendar.但是,本文档中没有提及Joda-Time数据类型.另外,我特别需要字符串DateTime使用UTC时区反序列化为对象,而不是GMT:尽管这两个区域非常相似,但是存在一些小差异,因此GMT对我来说是不可行的.
谢谢.
Red*_*der 24
显示的源代码DateTimeDeserializer使用反序列化期间DeserializationContext提供的时区ObjectMapper.如果您查看ObjectMapperAPI,您会看到有设置时区的方法:
public ObjectMapper setTimeZone(TimeZone tz)
Run Code Online (Sandbox Code Playgroud)
因此,您可以使用此方法配置您ObjectMapper的时区并将时区设置为正确的时区.
对于默认值,似乎Javadoc说了一件事,但代码显示了另一个.
Javadoc ObjectMapper.setTimeZone(TimeZone tz):
/**
* Method for overriding default TimeZone to use for formatting.
* Default value used is {@link TimeZone#getDefault()}.
*/
Run Code Online (Sandbox Code Playgroud)
但是,代码明确设置时区:
protected final static BaseSettings DEFAULT_BASE = new BaseSettings(
...
// TimeZone.getDefault()
TimeZone.getTimeZone("GMT"),
...
Run Code Online (Sandbox Code Playgroud)
所以,显然,它实际上使用的是GMT,而不是默认的JVM默认值.
我想说,最好的选择可能不是依赖于此而是自己设定ObjectMapper.setTimeZone(TimeZone tz).
Bas*_*que 17
对于商业应用,UTC和GMT之间没有实际区别.唯一的区别在于亚秒级分辨率和每隔几年增加一次闰秒.对于科学,天文学,卫星跟踪和此类应用程序而言,差异可能很大,但这种情况很少见.
我不认识杰克逊.但从看着你链接的文档,它看起来像他们要么序列化(一)自1970年1月1日,UTC,或(b)的字符串格式的毫秒数,默认为ISO 8601格式:"1970-01- 01T00:00:00.000 + 0000" .因此,为了回答关于时区的问题,听起来默认情况下杰克逊总是使用UTC(没有时区偏移)进行序列化,这是正确的方法.如果您关心当时正在使用的时区,则应在单独的字段中记录该事实(什么时区).
这两个序列化值(毫秒和ISO 8601字符串)都可以与Joda-Time DateTime实例的构造函数一起使用.
String dateTimeString = "2013-11-22T18:37:55.645+0000";
org.joda.time.DateTime myDateTime = org.joda.time.format.ISODateTimeFormat.dateTime().withZoneUTC().parseDateTime( dateTimeString );
Run Code Online (Sandbox Code Playgroud)
和…
Long millisSinceEpoch = 1385495462L;
org.joda.time.DateTime myDateTime = new org.joda.time.DateTime( millisSinceEpoch );
Run Code Online (Sandbox Code Playgroud)
如果您无法直接访问这些序列化值以提供给Joda-Time DateTime构造函数,那么让Jackson实例化java.util.Date/Calendar对象.将这些java.util.Date/Calendar对象提供给Joda-Time以实例化DateTime对象以进行进一步的工作.Joda-Time用户通常会这样做.
org.joda.time.DateTime myDateTime = new org.joda.time.DateTime( someJavaUtilDateFromJackson );
Run Code Online (Sandbox Code Playgroud)
您可以通过调用toDateTime()方法并传递所需的时区,轻松地将该UTC时间转换为Joda-Time中的其他时区.
org.joda.time.DateTimeZone kolkataTimeZone = org.joda.time.DateTimeZone.forID( "Asia/Kolkata" );
org.joda.time.DateTime dateTimeInKolkata = myDateTime.toDateTime( kolkataTimeZone );
Run Code Online (Sandbox Code Playgroud)
Joda-Time使用toDate方法轻松转换回java.util.Date .所以你在Joda-Time的大部分工作都要做,然后转换回java.util.Date与Jackson交流.当回到杰克逊时,我会将我的DateTimes切换回UTC,只是为了好的措施.
myDateTime.toDateTime( org.joda.time.DateTimeZone.UTC )
Run Code Online (Sandbox Code Playgroud)
您可以在StackOverflow.com上找到许多上述Joda-Time操作的示例.
我怀疑你做得太担心而且编码不够.只需尝试一些小实验,将值传入和传出Jackson和Joda-Time.你很快就会掌握它.我建议你让Jackson默认做任何想做的事,然后在Joda-Time中操纵.Joda-Time是针对日期时间的粗糙问题而建立的,而杰克逊可能不是.Joda-Time具有根据需要在时区之间进行调整的构造函数和方法.
在Java 8中,JSR 310:Date和Time API为Java平台带来了类似Joda-Time的类.期待看到像Jackson这样的框架更新为直接使用这些新类,同时弃用丑陋的java.util.Date/Calendar类.
看起来jackson-datatype-joda项目正试图为Joda-Time带来这种便利.但这对我来说似乎没有必要.您可以在java.util.Date/Calendar和Joda-Time之间进行转换,如上所述.
PS该项目文档的"Wiki"链接失败.所以我无法查看他们的文档.
我也在日期格式上苦苦挣扎,最后我找到了解决方案。我想使用格式,"2016-02-08T12:49:22.876Z"因为它是 ISO 8601 并且它被 JavaScript日期对象使用。我还想始终使用 UTC 时区。
我发现这可以使用以下代码完成:
final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setDateFormat(dateFormat);
System.out.println(objectMapper.writeValueAsString(new Date()));
Run Code Online (Sandbox Code Playgroud)
请注意X格式字符串中的字符。Java 7 支持它并在 ISO 8601 中指定时区。如SimpleDateFormat 中所述,如果时区偏移量为 0 (UTC),它会生成Z(而不是+00:00)。