Behaviour of GregorianCalendar.set() with daylight saving times

Viewed 1978

While troubleshooting a glitch, something strange in this method behavior appears.


Context

Some countries use to save some daylight by shifting time. For example, in the timezone "Europe/Paris", each year, time shifts 1 hour forwards end March and 1 hour backwards end October, both between 2 AM and 3 AM. This causes, for example, the date October, the 30th 2016 at 02:15 AM to exist twice.

Fortunately, both dates does not have the same timestamp (ms) amount, neither readable representation :

  • Before time shift : Sun Oct 30 02:15:00 CEST 2016 (+0200 from UTC)
  • After time shift : Sun Oct 30 02:15:00 CET 2016 (+0100 from UTC)

Issue

After instantiating a GregorianCalendar object at the Paris timezone (using SimpleDateFormat), we get our 02:15 AM before backward shift as expected.

But if we want to set minutes to this object using .set(), the +0200 offset information gets corrupted to +0100 ("same time", but after time shift) Is there any means of doing it this way, as the method .add() actually preserves the offset information?

Example

    // Instantiation
    GregorianCalendar gc1 = new GregorianCalendar(TimeZone.getTimeZone("Europe/Paris"));
    gc1.setTime(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss Z").parse("2016-10-30 02:15:00 +0200"));
    GregorianCalendar gc2 = (GregorianCalendar) gc1.clone();
    
    System.out.println(gc1.getTime()); // Output : Sun Oct 30 02:15:00 CEST 2016 ; OK
    System.out.println(gc2.getTime()); // Output : Sun Oct 30 02:15:00 CEST 2016 ; OK
    
    // Set/add minutes
    gc1.set(Calendar.MINUTE, 10);
    gc2.add(Calendar.MINUTE, 10);
    
    System.out.println(gc1.getTime()); // Output : Sun Oct 30 02:10:00 CET 2016 ; Unexpected
    System.out.println(gc2.getTime()); // Output : Sun Oct 30 02:25:00 CEST 2016 ; OK
1 Answers
Related