使用Joda-Time为Mongo插入形成正确的ISODate

我正在尝试更新需要ISODate格式的mongo中的日期字段。 在mongo中,它看起来像这样:

"crDt" : ISODate("2013-08-19T17:21:57.549Z") 

我正在使用的Java框架限制使用字符串作为我的测试参数,所以我试图将该字符串与DateTimeFormatter一起使用,以使其进入正确的ISODateTimeFormat ,然后将其传递给mongo。 我不能只传入一个看起来像我上面的字符串。 试图这样做搞砸了mongo的领域。 我正在使用的Joda-Time代码的相关位如下所示:

 //I can't get this right. String crDt = "2013-01-19T15:28:58.851Z"; DateTimeFormatter parser = ISODateTimeFormat.dateHourMinuteSecondMillis(); parser.parseDateTime(crDt); // this method updates the record in mongo. This method totally works, so no // point in pasting it here, I just can't get the parser object correct to be // in the correct format once inserted, it needs to be the correct ISODate form. mongo.setCrDt(recordId, parser); 

当代码运行时,我从.parseDateTime方法得到这样的错误:

 java.lang.IllegalArgumentException: Invalid format: "2013-01-19T15:28:58.851Z" is malformed at "Z" at org.joda.time.format.DateTimeFormatter.parseDateTime(DateTimeFormatter.java:866) 

我可以告诉我给出的字符串是不正确的解析。 我试过离开Z ,我尝试了其他组合,但每次它说它都是畸形的。 所以基本上,我的起始字符串需要什么来使.parseDateTime工作并给我一个看起来正确的对象?

编辑:

更新以尝试下面提供的建议。 我现在遇到的问题是IllegalArgumentException,无法序列化类org.joda.time.DateTime。 所以它似乎坚持joda时间对象在禁止? 我还查看了另一个建议,查看了像Spring Data这样的mapper框架。 看起来还有很多东西需要进入这个。 真的没有简单的方法可以将其持久化为mongo吗?

EDIT2:

好的,我想我现在拥有它。 我可能没有完全掌握所有的机制,但是BasicDBObject对于DateTime不会很好。 日期对象似乎是唯一的方法,至少在我正在处理的实现中。 我做了以下事情:

 DateTimeFormatter parser = ISODateTimeFormat.dateTime(); DateTime result; Date newResult; result = parser.parseDateTime(crDt); newResult = result.toDate(); 

然后我传入了newResult for BasicDBObject,然后在mongo中更新记录。 它工作正常,记录正确更新。

您的输入字符串格式是正确的,只要用于表示UTC即可。

更改解析器以使用与此格式匹配的解析器:

 DateTimeFormatter parser = ISODateTimeFormat.dateTime(); 

你的其余部分对我来说没有多大意义。 您不应该传递parser ,而是传递parseDateTime的返回值,您似乎没有捕获它。

 DateTime result = parser.parseDateTime(crDt); mongo.setCrDt(recordId, result.toDate()); 

最后一行是否有效取决于该函数接受的内容。

我通过在Service类的构造函数中添加“Encoding Hook”解决了这个问题,我在其中对MongoDB进行了更新。 这将允许您在代码中使用org.joda.time.DateTime,并将其保存为MongoDB中的java.util.Date。

MyService.java

 @Inject public MyService(com.mongodb.Client client) { BSON.addEncodingHook(DateTime.class, new JodaTimeTransformer()); BSON.addDecodingHook(Date.class, new JodaTimeTransformer()); this.mongoClient = mongoClient; } 

JodaTimeTransformer.java

 import java.util.Date; import org.joda.time.DateTime; public class JodaTimeTransformer implements org.bson.Transformer { @Override public Object transform(Object o) { if(o instanceof DateTime) { return ((DateTime)o).toDate(); } else if(o instanceof Date) { return new DateTime((Date) o); } throw new IllegalArgumentException("JodaTimeTransformer can only be used with DateTime or Date"); } } 

马特约翰逊的回答是正确的。 但它可能更简单:将( ISO 8601 )字符串直接传递给DateTime的构造函数。 不需要格式化程序。

注意时区。 与java.util.Date对象不同,Joda-Time中的DateTime对象确实知道自己指定的时区。 您是否希望为DateTime对象分配JVM的默认时区,没有时区(UTC)或特定时区?

为日期时间分配默认时区。

 DateTime dateTime = new DateTime( "2013-01-19T15:28:58.851Z" ); 

对于指定的UTC / GMT的日期时间(无时区偏移)。

 DateTime dateTime = new DateTime( "2013-01-19T15:28:58.851Z", DateTimeZone.UTC ); 

对于指定特定时区的日期时间。

 DateTime dateTime = new DateTime( "2013-01-19T15:28:58.851Z", DateTimeZone.forId( "Europe/Paris" ) );