Menu

#82 Illegal instant in PersistenLocalDateTime

open
nobody
5
2012-10-08
2009-10-28
Anonymous
No

Trying to persist a local datetime which is invalid in the default time zone due to daylight saving transitions fails.

Eg. trying to persist 2010-03-28T02:45:00.000 with default time zone set to Europe/Oslo causes exception to be thrown: java.lang.IllegalArgumentException: Illegal instant due to time zone offset transition: 2010-03-28T01:45:00.000.

This is because PersistentDateTime.nullSafeSet calls ((LocalDateTime) value).toDateTime(). I believe it is fixed by passing DateTimeZone.UTC as a parameter to doDateTime.

Discussion

  • Stephen Colebourne

    I agree that this is a problem, however using UTC will break data that has already been stored using this class.

     
  • Trygve Aasjord

    Trygve Aasjord - 2009-11-03

    Now logged in...

    I was a too quick to assume simply passing DateTimeZone.UTC as a parameter to toDateTime would fix it, it will store the wrong time. However, in nullSafeSet, by additionally calling PreparedStatement.setTimestamp with a Calendar instance with a UTC time zone, instead of passing it on to TimestampType, I got the correct result.

    How will this break existing data? As a LocalDateTime, the returned value from nullSafeGet should not care what timezone the data was saved in - if timezone information exists at all in the database column.

     
  • Stephen Colebourne

    The problem is not whether the DB holds time zone info or not, but that the java.sql.Timestamp does. That class implicitly uses the local time zone of the machine to define the date/time fields, hence making a change breaks code.

    One option would be to create a new Persistent LocalDateTimeAsUTC class

     
  • Trygve Aasjord

    Trygve Aasjord - 2009-11-10

    I finally got around to test it a bit more, it doesn't break my existing data (provided you don't apply UTC in nullSafeGet). Timestamp uses local time zone but it is up to the JDBC driver to take this into account in it's implementation of PreparedStatement.setTimestamp(int, Timestamp, Calendar). Unfortunately it seems that drivers implement it differently. I get different values with jtds compared to hsqldb with the same code and data, maybe hsqldb even ignores the argument. And although it doesn't break existing data or "valid" datetimes, with jtds 2010-03-28T02:45:00.000 gets persisted as 2010-03-28T03:45:00.000, which is almost/at least just as bad as an exception.

    In conlusion I admit that there may be no quick fix for this.

     
  • Chris Carruthers

    I've also hit this problem.
    My initial reaction was to pass the timezone to toDateTime, but I can see it's not a good idea.
    Any progress or further ideas since 2009?

     

Log in to post a comment.

MongoDB Logo MongoDB