From: Yoshito Umaoka Date: Tue, 20 Feb 2018 22:38:21 +0000 (+0000) Subject: ICU-13566 Support negative daylight savings in SimpleTimeZone. X-Git-Tag: release-61-rc~69 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=15b2113603169ac38bc89467a0a6e0c707a432e9;p=icu ICU-13566 Support negative daylight savings in SimpleTimeZone. X-SVN-Rev: 40954 --- diff --git a/icu4c/source/i18n/simpletz.cpp b/icu4c/source/i18n/simpletz.cpp index e17d14cc7b4..57a7ba8ed75 100644 --- a/icu4c/source/i18n/simpletz.cpp +++ b/icu4c/source/i18n/simpletz.cpp @@ -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 { diff --git a/icu4c/source/i18n/unicode/simpletz.h b/icu4c/source/i18n/unicode/simpletz.h index 5b802632b0d..3ae08077e3b 100644 --- a/icu4c/source/i18n/unicode/simpletz.h +++ b/icu4c/source/i18n/unicode/simpletz.h @@ -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; diff --git a/icu4c/source/test/intltest/tzregts.cpp b/icu4c/source/test/intltest/tzregts.cpp index b749c2d4422..c5f59d9182d 100644 --- a/icu4c/source/test/intltest/tzregts.cpp +++ b/icu4c/source/test/intltest/tzregts.cpp @@ -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 */ diff --git a/icu4c/source/test/intltest/tzregts.h b/icu4c/source/test/intltest/tzregts.h index 2d7f7ef13f8..46e43cd2502 100644 --- a/icu4c/source/test/intltest/tzregts.h +++ b/icu4c/source/test/intltest/tzregts.h @@ -49,6 +49,7 @@ public: void TestJDK12API(void); void Test4184229(void); UBool checkCalendar314(GregorianCalendar *testCal, TimeZone *testTZ); + void TestNegativeDaylightSaving(void); protected: diff --git a/icu4j/main/classes/core/src/com/ibm/icu/util/SimpleTimeZone.java b/icu4j/main/classes/core/src/com/ibm/icu/util/SimpleTimeZone.java index f91d80f76b0..94dc82292af 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/util/SimpleTimeZone.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/util/SimpleTimeZone.java @@ -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(); } } diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneRegressionTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneRegressionTest.java index d1433400615..4f18c38022d 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneRegressionTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneRegressionTest.java @@ -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