Java Driver IsoDate Parses to wrong time

662 views
Skip to first unread message

Brendon Puntin

unread,
Apr 30, 2015, 3:14:19 PM4/30/15
to mongo...@googlegroups.com
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);
    }


here is a test to expose that the issue lies in the http://api.mongodb.org/java/3.0/org/bson/json/JsonReader.html IsoDate parser:

  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);
    }


Artem Khodyush

unread,
Apr 30, 2015, 8:38:55 PM4/30/15
to mongo...@googlegroups.com

Replacing hh:mm:ssz  with 
HH:mm:ssz in that line should fix it

Jeff Yemin

unread,
May 1, 2015, 11:40:56 AM5/1/15
to mongo...@googlegroups.com
Hi Brendon,

It looks like there's a simple fix for this. Please open an issue at https://jira.mongodb.org/browse/JAVA so we can track it and get the fix into the next release.

As a workaround, please try using just two characters for milliseconds, e.g.

String s = "2013-10-04T12:07:30.44Z"


Regards,
Jeff 

Brendon

unread,
May 1, 2015, 3:19:25 PM5/1/15
to mongo...@googlegroups.com
thanks for the quick help!
I think this fixes it :)  ...
Reply all
Reply to author
Forward
0 new messages