Search code examples
javadatejodatimedate-conversion

Good way to convert integer YYYYMMDD into java.util.Date with local time zone


I understand this question could look like FAQ subject but critical things here is time zone and performance. I have integer YYYYMMDD date (20150131 is example). Here is good 'almost working' solution:

import org.joda.time.DateTime;
import java.util.Date;

// ...

public Date extract(final int intDate) {
    Date result = null;

    try {
        result = new DateTime(
                intDate / 10000,
                (intDate / 100) % 100,
                intDate % 100,
                0,
                0,
                0,
                0).toDate();

    } catch (final IllegalArgumentException e) {
        // Log failure
    }
    return result;
}

'almost' is because having 0x0126810d and EET (UTC+2 / +3 when DST) time zone I receive:

java.lang.IllegalArgumentException: Illegal instant due to time zone offset transition: 1930-06-20T22:00:00.000

At least using JODA 1.6. I cannot switch easily. But I'd like it to be 1930-06-21T00:00:00.000+02:00 and I don't care about UTC representation.

  1. Is it possible at all (can java.util.date store such date)?
  2. OK, any better high performance way to achieve this (JODA is just remedy here, not critical)?

Yes, I understand this time does not exist:

roman@node4:$ zdump -v Europe/Kiev | grep 1930
Europe/Kiev  Fri Jun 20 21:59:59 1930 UTC = Fri Jun 20 23:59:59 1930 EET isdst=0 gmtoff=7200
Europe/Kiev  Fri Jun 20 22:00:00 1930 UTC = Sat Jun 21 01:00:00 1930 MSK isdst=0 gmtoff=10800

Solution

  • OK, finally got the following fragment and it works most close to my expectations. Like SDF but many times faster - like no string parsing just to get digits:

    import org.joda.time.DateTime;
    import org.joda.time.LocalDate;
    
    public static Date toDateJoda(int intDate) {
        LocalDate ldt = new LocalDate(
            intDate / 10000,
            (intDate / 100) % 100,
            intDate % 100);
    
        DateTime dt = ldt.toDateTimeAtStartOfDay();
        return dt.toDate();
    }
    

    Parses everything and gets next valid date / time for cases like mine.