decodeRules(status);
- if (savingsDST <= 0) {
+ if (savingsDST == 0) {
status = U_ILLEGAL_ARGUMENT_ERROR;
}
}
void
SimpleTimeZone::setDSTSavings(int32_t millisSavedDuringDST, UErrorCode& status)
{
- if (millisSavedDuringDST <= 0) {
+ if (millisSavedDuringDST == 0) {
status = U_ILLEGAL_ARGUMENT_ERROR;
}
else {
* 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
*/
* 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;
#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"
CASE(16, TestJDK12API);
CASE(17, Test4176686);
CASE(18, Test4184229);
+ CASE(19, TestNegativeDaylightSaving);
default: name = ""; break;
}
}
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;
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 */
void TestJDK12API(void);
void Test4184229(void);
UBool checkCalendar314(GregorianCalendar *testCal, TimeZone *testTZ);
+ void TestNegativeDaylightSaving(void);
protected:
* 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) {
throw new UnsupportedOperationException("Attempt to modify a frozen SimpleTimeZone instance.");
}
- if (millisSavedDuringDST <= 0) {
+ if (millisSavedDuringDST == 0) {
throw new IllegalArgumentException();
}
dst = millisSavedDuringDST;
* 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
decodeRules();
- if (_dst <= 0) {
+ if (_dst == 0) {
throw new IllegalArgumentException();
}
}
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];
}
}
}
+
+ @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