Is there something that we're overlooking, or is this a bug?  Thanks
for any help.

$ cat DividedDateTimeFieldDaylightSavingRoundingBug.java
import org.joda.time.*;
import org.joda.time.chrono.*;
import org.joda.time.field.*;

public class DividedDateTimeFieldDaylightSavingRoundingBug {
  private static final DateTimeZone LOS_ANGELES =
      DateTimeZone.forID("America/Los_Angeles");

  /**
   * Demonstrate that rounding the second 1AM of a DST-change day back to the
   * nearest 10 minutes actually rounds it back by an hour.
   */
  public static void main(String[] args) {
    Instant fallSecond1Am = new Instant(1289120400000L);

    // Sanity checks.
    /*
     * 1. We really do have the second 1:00AM of the fall DST switchover.
     * Confirm this (a) by adding one hour to the first 1:00AM and (b) by
     * comparing toString() to the expected value:
     */
    Instant fallFirst1Am = new DateTime()
        .withZone(LOS_ANGELES)
        .withDate(2010, 11, 7)
        .withTime(1, 0, 0, 0)
        .toInstant();
    assertEquals(
        fallSecond1Am, fallFirst1Am.plus(Hours.ONE.toStandardDuration()));
    assertEquals("2010-11-07T01:00:00.000-07:00",
        new DateTime(fallFirst1Am.getMillis(), LOS_ANGELES).toString());
    assertEquals("2010-11-07T01:00:00.000-08:00",
        new DateTime(fallSecond1Am.getMillis(), LOS_ANGELES).toString());
    /*
     * 2. Rounding the FIRST 1AM back to the nearest 10-minute boundary (i.e.,
     * itself) is a no-op, as expected:
     */
    assertEquals(fallFirst1Am, floor10Minutes(fallFirst1Am));

    /*
     * Rounding the SECOND 1AM back to the nearest 10-minute boundary (i.e.,
     * itself) should be a no-op, too, but Joda instead rounds a full hour back
     * to the FIRST 1:00AM (note that the times in the failure message are UTC):
     *
     * expected:<2010-11-07T09:00:00.000Z> but was:<2010-11-07T08:00:00.000Z>
     */
    assertEquals(fallSecond1Am, floor10Minutes(fallSecond1Am));
  }

  private static Instant floor10Minutes(Instant in) {
    return new Instant(getTenMinuteField().roundFloor(in.getMillis()));
  }

  private static DividedDateTimeField getTenMinuteField() {
    DateTimeFieldType minuteFieldType = DateTimeFieldType.minuteOfHour();
    // Note: If we use getInstanceUTC() instead of GST, the test passes.
    Chronology chronology = ISOChronology.getInstance(LOS_ANGELES);
    DateTimeField oneMinuteField = minuteFieldType.getField(chronology);
    return new DividedDateTimeField(oneMinuteField, minuteFieldType, 10);
  }

  private static void assertEquals(Object expected, Object actual) {
    if (!expected.equals(actual)) {
      throw new RuntimeException(
          "expected:<" + expected + "> but was:<" + actual + ">");
    }
  }
}
$ javac -classpath .:joda-time-1.6.2.jar
DividedDateTimeFieldDaylightSavingRoundingBug.java && java -classpath
.:joda-time-1.6.2.jar DividedDateTimeFieldDaylightSavingRoundingBug
Exception in thread "main" java.lang.RuntimeException:
expected:<2010-11-07T09:00:00.000Z> but was:<2010-11-07T08:00:00.000Z>
        at 
DividedDateTimeFieldDaylightSavingRoundingBug.assertEquals(DividedDateTimeFieldDaylightSavingRoundingBug.java:63)
        at 
DividedDateTimeFieldDaylightSavingRoundingBug.main(DividedDateTimeFieldDaylightSavingRoundingBug.java:46)

------------------------------------------------------------------------------
Benefiting from Server Virtualization: Beyond Initial Workload 
Consolidation -- Increasing the use of server virtualization is a top
priority.Virtualization can reduce costs, simplify management, and improve 
application availability and disaster protection. Learn more about boosting 
the value of server virtualization. http://p.sf.net/sfu/vmware-sfdev2dev
_______________________________________________
Joda-interest mailing list
Joda-interest@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/joda-interest

Reply via email to