Hi,
I wanted to bring this to your attention. I've been tracking down some issues I've been seeing and it appears that the ISODate Data Type is not parsed properly in some cases.
I was able to create a test to reproduce a bad value. The problem seems to be in the org.bson.JsonReader
This is the output from the test below, using an ISODate String of
2013-10-04T12:07:30.443Z:
jodaTime:1380888450443 date:Fri Oct 04 08:07:30 EDT 2013
docuTime:1380845250443 date:Thu Oct 03 20:07:30 EDT 2013
I believe the jodaTime is correct.
Steps to reproduce:
relevant maven dependencies:
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency> <!-- for joda time -->
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
test to reproduce:
// parse using joda ISODateTimeFormat, convert to java.util.Date, and get the time.
public long parseDateUsingJodaTime(String isoDateString) {
return org.joda.time.format.ISODateTimeFormat
.dateTimeParser()
.parseDateTime(isoDateString)
.toDate()
.getTime();
}
public long parseDateUsingDocument(String isoString) {
String bson = String.format("{\"sample\" : ISODate(\"%s\")}", isoString);
return org.bson.Document
.parse(bson)
.get("sample", Date.class)
.getTime();
}
@Test
public void whatTheDates() {
String s = "2013-10-04T12:07:30.443Z";
long jodaTime = parseDateUsingJodaTime(s);
long documentTime = parseDateUsingDocument(s);
System.out.println("jodaTime:" + jodaTime + "\tdate:" + new Date(jodaTime));
System.out.println("docuTime:" + documentTime + "\tdate:" + new Date(documentTime));
assertEquals(jodaTime, documentTime);
}
public long mimicOf_jsonReader_visitISODateTimeConstructor(String s) {
String[] patterns = {"yyyy-MM-dd", "yyyy-MM-dd'T'hh:mm:ssz", "yyyy-MM-dd'T'hh:mm:ss.SSSz"};
SimpleDateFormat format = new SimpleDateFormat(patterns[0], Locale.ENGLISH);
ParsePosition pos = new ParsePosition(0);
if (s.endsWith("Z")) {
s = s.substring(0, s.length() - 1) + "GMT-00:00";
}
//System.out.println("parsing formatted string: " + s);
for (final String pattern : patterns) {
format.applyPattern(pattern);
format.setLenient(true);
pos.setIndex(0);
Date date = format.parse(s, pos);
if (date != null && pos.getIndex() == s.length()) {
return date.getTime();
}
}
throw new RuntimeException("ran out of things to try.");
}
@Test
public void toTheSource() {
String s = "2013-10-04T12:07:30.443Z";
long documentTime = parseDateUsingDocument(s);
long jsonTime = mimicOf_jsonReader_visitISODateTimeConstructor(s);
System.out.println("docuTime:" + documentTime + "\tdate:" + new Date(documentTime));
System.out.println("jsonDate:" + jsonTime + "\tdate:" + new Date(jsonTime));
assertEquals(documentTime, jsonTime);
}