ICU-13566 Support negative daylight savings in SimpleTimeZone.
X-SVN-Rev: 40954
This commit is contained in:
parent
3c7a6e30ab
commit
15b2113603
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
void TestJDK12API(void);
|
||||
void Test4184229(void);
|
||||
UBool checkCalendar314(GregorianCalendar *testCal, TimeZone *testTZ);
|
||||
void TestNegativeDaylightSaving(void);
|
||||
|
||||
|
||||
protected:
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user