]> granicus.if.org Git - icu/commitdiff
ICU-13566 Support negative daylight savings in SimpleTimeZone.
authorYoshito Umaoka <y.umaoka@gmail.com>
Tue, 20 Feb 2018 22:38:21 +0000 (22:38 +0000)
committerYoshito Umaoka <y.umaoka@gmail.com>
Tue, 20 Feb 2018 22:38:21 +0000 (22:38 +0000)
X-SVN-Rev: 40954

icu4c/source/i18n/simpletz.cpp
icu4c/source/i18n/unicode/simpletz.h
icu4c/source/test/intltest/tzregts.cpp
icu4c/source/test/intltest/tzregts.h
icu4j/main/classes/core/src/com/ibm/icu/util/SimpleTimeZone.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneRegressionTest.java

index e17d14cc7b4f0ac500f943fb7c021aa3175bcdda..57a7ba8ed75d219bbe38fead5fcd476f51b2b1d5 100644 (file)
@@ -177,7 +177,7 @@ void SimpleTimeZone::construct(int32_t rawOffsetGMT,
 
     decodeRules(status);
 
-    if (savingsDST <= 0) {
+    if (savingsDST == 0) {
         status = U_ILLEGAL_ARGUMENT_ERROR;
     }
 }
@@ -686,7 +686,7 @@ SimpleTimeZone::setRawOffset(int32_t offsetMillis)
 void 
 SimpleTimeZone::setDSTSavings(int32_t millisSavedDuringDST, UErrorCode& status) 
 {
-    if (millisSavedDuringDST <= 0) {
+    if (millisSavedDuringDST == 0) {
         status = U_ILLEGAL_ARGUMENT_ERROR;
     }
     else {
index 5b802632b0de78504cafc14ec81c876222b482e3..3ae08077e3b7f2284c5b2f7196390e7e6e3b1514 100644 (file)
@@ -647,7 +647,8 @@ public:
      * Sets the amount of time in ms that the clock is advanced during DST.
      * @param millisSavedDuringDST the number of milliseconds the time is
      * advanced with respect to standard time when the daylight savings rules
-     * are in effect. A positive number, typically one hour (3600000).
+     * are in effect. Typically one hour (+3600000). The amount could be negative,
+     * but not 0.
      * @param status  An UErrorCode to receive the status.
      * @stable ICU 2.0
      */
@@ -657,7 +658,8 @@ public:
      * Returns the amount of time in ms that the clock is advanced during DST.
      * @return the number of milliseconds the time is
      * advanced with respect to standard time when the daylight savings rules
-     * are in effect. A positive number, typically one hour (3600000).
+     * are in effect. Typically one hour (+3600000). The amount could be negative,
+     * but not 0.
      * @stable ICU 2.0
      */
     virtual int32_t getDSTSavings(void) const;
index b749c2d4422bab1cce3c340a247b9f05c70792fd..c5f59d9182d1659a11c1dc3cec3b1f0912d4c631 100644 (file)
@@ -12,6 +12,7 @@
 #include "unicode/simpletz.h"
 #include "unicode/smpdtfmt.h"
 #include "unicode/strenum.h"
+#include "unicode/gregocal.h"
 #include "tzregts.h"
 #include "calregts.h"
 #include "cmemory.h"
@@ -46,6 +47,7 @@ TimeZoneRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &
         CASE(16, TestJDK12API);
         CASE(17, Test4176686);
         CASE(18, Test4184229);
+        CASE(19, TestNegativeDaylightSaving);
         default: name = ""; break;
     }
 }
@@ -709,10 +711,10 @@ TimeZoneRegressionTest::Test4154525()
     int32_t DATA [] = {
         1, GOOD,
         0, BAD,
-        -1, BAD,
+        -1, GOOD,   // #13566 updates SimpleTimeZone to support negative DST saving amount
         60*60*1000, GOOD,
-        INT32_MIN, BAD,
-        // Integer.MAX_VALUE, ?, // no upper limit on DST savings at this time
+        INT32_MAX, GOOD,    // no upper limit on DST savings at this time
+        INT32_MIN, GOOD     // no lower limit as well
     };
 
     UErrorCode status = U_ZERO_ERROR;
@@ -1206,4 +1208,61 @@ void TimeZoneRegressionTest::Test4184229() {
     delete zone;
 }
 
+void TimeZoneRegressionTest::TestNegativeDaylightSaving() {
+    UErrorCode status = U_ZERO_ERROR;
+    int32_t stdOff = 1 * 60*60*1000;    // Standard offset UTC+1
+    int save = -1 * 60*60*1000;     // DST saving amount -1 hour
+    SimpleTimeZone stzDublin(stdOff, "Dublin-2018",
+                                UCAL_OCTOBER, -1, -UCAL_SUNDAY, 2*60*60*1000,
+                                UCAL_MARCH, -1, -UCAL_SUNDAY, 1*60*60*1000,
+                                save, status);
+    failure(status, "SimpleTimeZone constructor");
+
+    if (save != stzDublin.getDSTSavings()) {
+        errln((UnicodeString)"FAIL: DST saving is not " + save);
+    }
+
+    GregorianCalendar cal(* TimeZone::getGMT(), status);
+    failure(status, "GregorianCalendar constructor");
+
+    UDate testDate;
+    int32_t rawOffset;
+    int32_t dstOffset;
+
+    cal.set(2018, UCAL_JANUARY, 15, 0, 0, 0);
+    testDate = cal.getTime(status);
+    failure(status, "calendar getTime() - Jan 15");
+
+    if (!stzDublin.inDaylightTime(testDate, status)) {
+        errln("FAIL: The test date (Jan 15) must be in DST.");
+    }
+    failure(status, "inDaylightTime() - Jan 15");
+
+    stzDublin.getOffset(testDate, FALSE, rawOffset, dstOffset, status);
+    failure(status, "getOffset() - Jan 15");
+    if (rawOffset != stdOff || dstOffset != save) {
+        errln((UnicodeString)"FAIL: Expected [stdoff=" + stdOff + ",save=" + save
+            + "] on the test date (Jan 15), actual[stdoff=" + rawOffset
+            + ",save=" + dstOffset + "]");
+    }
+
+    cal.set(2018, UCAL_JULY, 15, 0, 0, 0);
+    testDate = cal.getTime(status);
+    failure(status, "calendar getTime() - Jul 15");
+
+    if (stzDublin.inDaylightTime(testDate, status)) {
+        errln("FAIL: The test date (Jul 15) must be in DST.");
+    }
+    failure(status, "inDaylightTime() - Jul 15");
+
+    stzDublin.getOffset(testDate, FALSE, rawOffset, dstOffset, status);
+    failure(status, "getOffset() - Jul 15");
+    if (rawOffset != stdOff || dstOffset != 0) {
+        errln((UnicodeString)"FAIL: Expected [stdoff=" + stdOff + ",save=" + 0
+            + "] on the test date (Jul 15), actual[stdoff=" + rawOffset
+            + ",save=" + dstOffset + "]");
+    }
+}
+
+
 #endif /* #if !UCONFIG_NO_FORMATTING */
index 2d7f7ef13f8214977e4f9506c319cbf397140df8..46e43cd250241b7a4b2001489d154e6a96ba9a2a 100644 (file)
@@ -49,6 +49,7 @@ public:
     void TestJDK12API(void);
     void Test4184229(void);
     UBool checkCalendar314(GregorianCalendar *testCal, TimeZone *testTZ);
+    void TestNegativeDaylightSaving(void);
 
 
 protected:
index f91d80f76b04ea4c82169cf3438359e0b1fcfe2d..94dc82292af0d0d3490e26b40a64177e0be1350a 100644 (file)
@@ -540,7 +540,8 @@ public class SimpleTimeZone extends BasicTimeZone {
      * Sets the amount of time in ms that the clock is advanced during DST.
      * @param millisSavedDuringDST the number of milliseconds the time is
      * advanced with respect to standard time when the daylight savings rules
-     * are in effect. A positive number, typically one hour (3600000).
+     * are in effect. Typically one hour (+3600000). The amount could be negative,
+     * but not 0.
      * @stable ICU 2.0
      */
     public void setDSTSavings(int millisSavedDuringDST) {
@@ -548,7 +549,7 @@ public class SimpleTimeZone extends BasicTimeZone {
             throw new UnsupportedOperationException("Attempt to modify a frozen SimpleTimeZone instance.");
         }
 
-        if (millisSavedDuringDST <= 0) {
+        if (millisSavedDuringDST == 0) {
             throw new IllegalArgumentException();
         }
         dst = millisSavedDuringDST;
@@ -560,7 +561,8 @@ public class SimpleTimeZone extends BasicTimeZone {
      * Returns the amount of time in ms that the clock is advanced during DST.
      * @return the number of milliseconds the time is
      * advanced with respect to standard time when the daylight savings rules
-     * are in effect. A positive number, typically one hour (3600000).
+     * are in effect. Typically one hour (3600000). The amount could be negative,
+     * but not 0.
      * @stable ICU 2.0
      */
     @Override
@@ -1015,7 +1017,7 @@ public class SimpleTimeZone extends BasicTimeZone {
 
         decodeRules();
 
-        if (_dst <= 0) {
+        if (_dst == 0) {
             throw new IllegalArgumentException();
         }
     }
index d14334006155bd31f4f4a433eac3e0168d3d6f8d..4f18c38022da16286f6e978a123e7b31e29fa820 100644 (file)
@@ -394,10 +394,10 @@ public class TimeZoneRegressionTest extends TestFmwk {
         int[] DATA = {
             1, GOOD,
             0, BAD,
-            -1, BAD,
+            -1, GOOD,   // #13566 updates SimpleTimeZone to support negative DST saving amount
             60*60*1000, GOOD,
-            Integer.MIN_VALUE, BAD,
-            // Integer.MAX_VALUE, ?, // no upper limit on DST savings at this time
+            Integer.MAX_VALUE, GOOD,    // no upper limit on DST savings at this time
+            Integer.MIN_VALUE, GOOD,    // no lower limit as well
         };
         for (int i=0; i<DATA.length; i+=2) {
             int savings = DATA[i];
@@ -1224,6 +1224,48 @@ public class TimeZoneRegressionTest extends TestFmwk {
             }
         }
     }
+
+    @Test
+    public void TestNegativeDaylightSaving() {
+        int stdOff = 1 * 60*60*1000;    // Standard offset UTC+1
+        int save = -1 * 60*60*1000;     // DST saving amount -1 hour
+        SimpleTimeZone stzDublin = new SimpleTimeZone(
+                1*60*60*1000, "Dublin-2018a",
+                Calendar.OCTOBER, -1, -Calendar.SUNDAY, 2*60*60*1000,
+                Calendar.MARCH, -1, -Calendar.SUNDAY, 1*60*60*1000,
+                save);
+        if (save != stzDublin.getDSTSavings()) {
+            errln("FAIL: DST saving is not " + save);
+        }
+
+        GregorianCalendar cal = new GregorianCalendar(TimeZone.GMT_ZONE);
+        Date testDate;
+        int[] offsets = new int[2];
+
+        cal.set(2018, Calendar.JANUARY, 15, 0, 0, 0);
+        testDate = cal.getTime();
+        if (!stzDublin.inDaylightTime(testDate)) {
+            errln("FAIL: The test date (Jan 15) must be in DST.");
+        }
+        stzDublin.getOffset(testDate.getTime(), false, offsets);
+        if (offsets[0] != stdOff || offsets[1] != save) {
+            errln("FAIL: Expected [stdoff=" + stdOff + ",save=" + save
+                    + "] on the test date (Jan 15), actual[stdoff=" + offsets[0]
+                    + ",save=" + offsets[1] + "]");
+        }
+
+        cal.set(2018, Calendar.JULY, 15, 0, 0, 0);
+        testDate = cal.getTime();
+        if (stzDublin.inDaylightTime(testDate)) {
+            errln("FAIL: The test date (Jul 15) must not be in DST.");
+        }
+        stzDublin.getOffset(testDate.getTime(), false, offsets);
+        if (offsets[0] != stdOff || offsets[1] != 0) {
+            errln("FAIL: Expected [stdoff=" + stdOff + ",save=" + 0
+                    + "] on the test date (Jul 15), actual[stdoff=" + offsets[0]
+                    + ",save=" + offsets[1] + "]");
+        }
+    }
 }
 
 //eof