exceljava-timezoneddatetimeexcel-dates

Convert from Excel datetime to ZonedDateTime


A datetime in Excel is saved as the number of days since 1900-01-01 (+1 as it thinks 1900-02-29 occurred). The fraction in the number is the time offset in the day.

This number has no concept of timezones. So 12.5 is 1900-01-12T12:00:00 in the timezone you have your spreadsheet open in. Open it in Colorado and it shows noon. Open it in Germany and it shows noon. It's not an instant, it's a LocalDateTime.

For our system where we store everything as an OffsetDateTime or ZonedDateTime (depending on how the datetime was passed to us) the logical thing to do I think is create a ZonedDateTime from this.

Which leads to the question, how do I create a ZonedDateTime, set to this Excel datetime number, in the local time zone?


Solution

  •     LocalDate msBaseDate = LocalDate.of(1899, Month.DECEMBER, 31);
    
        double dateFromExcel = 12.5;
        long nanosSinceBase = Math.round(dateFromExcel * TimeUnit.DAYS.toNanos(1));
        ZonedDateTime dateTime = msBaseDate.atStartOfDay()
                .plusNanos(nanosSinceBase)
                .atZone(ZoneId.systemDefault());
    
        System.out.println(dateTime);
    

    On my computer the output is:

    1900-01-12T12:00+01:00[Europe/Copenhagen]

    Since java.time only uses whole numbers, I am used its finest granularity, nanoseconds. This will overflow a long in year 2192, so for a future-proof solution you may consider adding the whole days separately and only converting the fraction to nanos.