OLD | NEW |
| (Empty) |
1 /* | |
2 ******************************************************************************* | |
3 * Copyright (C) 2007-2011, International Business Machines Corporation and
* | |
4 * others. All Rights Reserved. * | |
5 ******************************************************************************* | |
6 */ | |
7 #include "unicode/utypes.h" | |
8 | |
9 #if !UCONFIG_NO_FORMATTING | |
10 | |
11 #include "tzoffloc.h" | |
12 | |
13 #include "unicode/ucal.h" | |
14 #include "unicode/timezone.h" | |
15 #include "unicode/calendar.h" | |
16 #include "unicode/dtrule.h" | |
17 #include "unicode/tzrule.h" | |
18 #include "unicode/rbtz.h" | |
19 #include "unicode/simpletz.h" | |
20 #include "unicode/tzrule.h" | |
21 #include "unicode/smpdtfmt.h" | |
22 #include "unicode/gregocal.h" | |
23 | |
24 void | |
25 TimeZoneOffsetLocalTest::runIndexedTest( int32_t index, UBool exec, const char*
&name, char* /*par*/ ) | |
26 { | |
27 if (exec) { | |
28 logln("TestSuite TimeZoneOffsetLocalTest"); | |
29 } | |
30 switch (index) { | |
31 TESTCASE(0, TestGetOffsetAroundTransition); | |
32 default: name = ""; break; | |
33 } | |
34 } | |
35 | |
36 /* | |
37 * Testing getOffset APIs around rule transition by local standard/wall time. | |
38 */ | |
39 void | |
40 TimeZoneOffsetLocalTest::TestGetOffsetAroundTransition() { | |
41 const int32_t NUM_DATES = 10; | |
42 const int32_t NUM_TIMEZONES = 3; | |
43 | |
44 const int32_t HOUR = 60*60*1000; | |
45 const int32_t MINUTE = 60*1000; | |
46 | |
47 const int32_t DATES[NUM_DATES][6] = { | |
48 {2006, UCAL_APRIL, 2, 1, 30, 1*HOUR+30*MINUTE}, | |
49 {2006, UCAL_APRIL, 2, 2, 00, 2*HOUR}, | |
50 {2006, UCAL_APRIL, 2, 2, 30, 2*HOUR+30*MINUTE}, | |
51 {2006, UCAL_APRIL, 2, 3, 00, 3*HOUR}, | |
52 {2006, UCAL_APRIL, 2, 3, 30, 3*HOUR+30*MINUTE}, | |
53 {2006, UCAL_OCTOBER, 29, 0, 30, 0*HOUR+30*MINUTE}, | |
54 {2006, UCAL_OCTOBER, 29, 1, 00, 1*HOUR}, | |
55 {2006, UCAL_OCTOBER, 29, 1, 30, 1*HOUR+30*MINUTE}, | |
56 {2006, UCAL_OCTOBER, 29, 2, 00, 2*HOUR}, | |
57 {2006, UCAL_OCTOBER, 29, 2, 30, 2*HOUR+30*MINUTE}, | |
58 }; | |
59 | |
60 // Expected offsets by int32_t getOffset(uint8_t era, int32_t year, int32_t
month, int32_t day, | |
61 // uint8_t dayOfWeek, int32_t millis, UErrorCode& status) | |
62 const int32_t OFFSETS1[NUM_DATES] = { | |
63 // April 2, 2006 | |
64 -8*HOUR, | |
65 -7*HOUR, | |
66 -7*HOUR, | |
67 -7*HOUR, | |
68 -7*HOUR, | |
69 | |
70 // October 29, 2006 | |
71 -7*HOUR, | |
72 -8*HOUR, | |
73 -8*HOUR, | |
74 -8*HOUR, | |
75 -8*HOUR, | |
76 }; | |
77 | |
78 // Expected offsets by void getOffset(UDate date, UBool local, int32_t& rawO
ffset, | |
79 // int32_t& dstOffset, UErrorCode& ec) with local=TRUE | |
80 // or void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_
t duplicatedTimeOpt, | |
81 // int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) with | |
82 // nonExistingTimeOpt=kStandard/duplicatedTimeOpt=kStandard | |
83 const int32_t OFFSETS2[NUM_DATES][2] = { | |
84 // April 2, 2006 | |
85 {-8*HOUR, 0}, | |
86 {-8*HOUR, 0}, | |
87 {-8*HOUR, 0}, | |
88 {-8*HOUR, 1*HOUR}, | |
89 {-8*HOUR, 1*HOUR}, | |
90 | |
91 // Oct 29, 2006 | |
92 {-8*HOUR, 1*HOUR}, | |
93 {-8*HOUR, 0}, | |
94 {-8*HOUR, 0}, | |
95 {-8*HOUR, 0}, | |
96 {-8*HOUR, 0}, | |
97 }; | |
98 | |
99 // Expected offsets by void getOffsetFromLocal(UDate date, int32_t nonExisti
ngTimeOpt, | |
100 // int32_t duplicatedTimeOpt, int32_t& rawOffset, int32_t& dstOffset, UError
Code& status) with | |
101 // nonExistingTimeOpt=kDaylight/duplicatedTimeOpt=kDaylight | |
102 const int32_t OFFSETS3[][2] = { | |
103 // April 2, 2006 | |
104 {-8*HOUR, 0}, | |
105 {-8*HOUR, 1*HOUR}, | |
106 {-8*HOUR, 1*HOUR}, | |
107 {-8*HOUR, 1*HOUR}, | |
108 {-8*HOUR, 1*HOUR}, | |
109 | |
110 // October 29, 2006 | |
111 {-8*HOUR, 1*HOUR}, | |
112 {-8*HOUR, 1*HOUR}, | |
113 {-8*HOUR, 1*HOUR}, | |
114 {-8*HOUR, 0}, | |
115 {-8*HOUR, 0}, | |
116 }; | |
117 | |
118 UErrorCode status = U_ZERO_ERROR; | |
119 | |
120 int32_t rawOffset, dstOffset; | |
121 TimeZone* utc = TimeZone::createTimeZone("UTC"); | |
122 Calendar* cal = Calendar::createInstance(*utc, status); | |
123 if (U_FAILURE(status)) { | |
124 dataerrln("Calendar::createInstance failed: %s", u_errorName(status)); | |
125 return; | |
126 } | |
127 cal->clear(); | |
128 | |
129 // Set up TimeZone objects - OlsonTimeZone, SimpleTimeZone and RuleBasedTime
Zone | |
130 BasicTimeZone *TESTZONES[NUM_TIMEZONES]; | |
131 | |
132 TESTZONES[0] = (BasicTimeZone*)TimeZone::createTimeZone("America/Los_Angeles
"); | |
133 TESTZONES[1] = new SimpleTimeZone(-8*HOUR, "Simple Pacific Time", | |
134 UCAL_APRIL, 1, UCAL_SUNDAY, 2*HOUR, | |
135 UCAL_OCTOBER, -1, UCAL_SUNDAY, 2*HOUR, s
tatus); | |
136 if (U_FAILURE(status)) { | |
137 errln("SimpleTimeZone constructor failed"); | |
138 return; | |
139 } | |
140 | |
141 InitialTimeZoneRule *ir = new InitialTimeZoneRule( | |
142 "Pacific Standard Time", // Initial time Name | |
143 -8*HOUR, // Raw offset | |
144 0*HOUR); // DST saving amount | |
145 | |
146 RuleBasedTimeZone *rbPT = new RuleBasedTimeZone("Rule based Pacific Time", i
r); | |
147 | |
148 DateTimeRule *dtr; | |
149 AnnualTimeZoneRule *atzr; | |
150 const int32_t STARTYEAR = 2000; | |
151 | |
152 dtr = new DateTimeRule(UCAL_APRIL, 1, UCAL_SUNDAY, | |
153 2*HOUR, DateTimeRule::WALL_TIME); // 1st Sunday in April
, at 2AM wall time | |
154 atzr = new AnnualTimeZoneRule("Pacific Daylight Time", | |
155 -8*HOUR /* rawOffset */, 1*HOUR /* dstSavings */, dtr, | |
156 STARTYEAR, AnnualTimeZoneRule::MAX_YEAR); | |
157 rbPT->addTransitionRule(atzr, status); | |
158 if (U_FAILURE(status)) { | |
159 errln("Could not add DST start rule to the RuleBasedTimeZone rbPT"); | |
160 return; | |
161 } | |
162 | |
163 dtr = new DateTimeRule(UCAL_OCTOBER, -1, UCAL_SUNDAY, | |
164 2*HOUR, DateTimeRule::WALL_TIME); // last Sunday in Octo
ber, at 2AM wall time | |
165 atzr = new AnnualTimeZoneRule("Pacific Standard Time", | |
166 -8*HOUR /* rawOffset */, 0 /* dstSavings */, dtr, | |
167 STARTYEAR, AnnualTimeZoneRule::MAX_YEAR); | |
168 rbPT->addTransitionRule(atzr, status); | |
169 if (U_FAILURE(status)) { | |
170 errln("Could not add STD start rule to the RuleBasedTimeZone rbPT"); | |
171 return; | |
172 } | |
173 | |
174 rbPT->complete(status); | |
175 if (U_FAILURE(status)) { | |
176 errln("complete() failed for RuleBasedTimeZone rbPT"); | |
177 return; | |
178 } | |
179 | |
180 TESTZONES[2] = rbPT; | |
181 | |
182 // Calculate millis | |
183 UDate MILLIS[NUM_DATES]; | |
184 for (int32_t i = 0; i < NUM_DATES; i++) { | |
185 cal->clear(); | |
186 cal->set(DATES[i][0], DATES[i][1], DATES[i][2], DATES[i][3], DATES[i][4]
); | |
187 MILLIS[i] = cal->getTime(status); | |
188 if (U_FAILURE(status)) { | |
189 errln("cal->getTime failed"); | |
190 return; | |
191 } | |
192 } | |
193 | |
194 SimpleDateFormat df(UnicodeString("yyyy-MM-dd HH:mm:ss"), status); | |
195 if (U_FAILURE(status)) { | |
196 dataerrln("Failed to initialize a SimpleDateFormat - %s", u_errorName(st
atus)); | |
197 } | |
198 df.setTimeZone(*utc); | |
199 UnicodeString dateStr; | |
200 | |
201 // Test getOffset(uint8_t era, int32_t year, int32_t month, int32_t day, | |
202 // uint8_t dayOfWeek, int32_t millis, UErrorCode& status) | |
203 for (int32_t i = 0; i < NUM_TIMEZONES; i++) { | |
204 for (int32_t d = 0; d < NUM_DATES; d++) { | |
205 status = U_ZERO_ERROR; | |
206 int32_t offset = TESTZONES[i]->getOffset(GregorianCalendar::AD, DATE
S[d][0], DATES[d][1], DATES[d][2], | |
207 UCAL_SUNDAY, DATES[d][5], status
); | |
208 if (U_FAILURE(status)) { | |
209 errln((UnicodeString)"getOffset(era,year,month,day,dayOfWeek,mil
lis,status) failed for TESTZONES[" + i + "]"); | |
210 } else if (offset != OFFSETS1[d]) { | |
211 dateStr.remove(); | |
212 df.format(MILLIS[d], dateStr); | |
213 dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i
+ "] at " | |
214 + dateStr + "(standard) - Got: " + offset + " Expected:
" + OFFSETS1[d]); | |
215 } | |
216 } | |
217 } | |
218 | |
219 // Test getOffset(UDate date, UBool local, int32_t& rawOffset, | |
220 // int32_t& dstOffset, UErrorCode& ec) with local = TRUE | |
221 for (int32_t i = 0; i < NUM_TIMEZONES; i++) { | |
222 for (int32_t m = 0; m < NUM_DATES; m++) { | |
223 status = U_ZERO_ERROR; | |
224 TESTZONES[i]->getOffset(MILLIS[m], TRUE, rawOffset, dstOffset, statu
s); | |
225 if (U_FAILURE(status)) { | |
226 errln((UnicodeString)"getOffset(date,local,rawOfset,dstOffset,ec
) failed for TESTZONES[" + i + "]"); | |
227 } else if (rawOffset != OFFSETS2[m][0] || dstOffset != OFFSETS2[m][1
]) { | |
228 dateStr.remove(); | |
229 df.format(MILLIS[m], dateStr); | |
230 dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i
+ "] at " | |
231 + dateStr + "(wall) - Got: " | |
232 + rawOffset + "/" + dstOffset | |
233 + " Expected: " + OFFSETS2[m][0] + "/" + OFFSETS2[m][1])
; | |
234 } | |
235 } | |
236 } | |
237 | |
238 // Test getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t d
uplicatedTimeOpt, | |
239 // int32_t& rawOffset, int32_t& dstOffset, UErroCode& status) | |
240 // with nonExistingTimeOpt=kStandard/duplicatedTimeOpt=kStandard | |
241 for (int32_t i = 0; i < NUM_TIMEZONES; i++) { | |
242 for (int m = 0; m < NUM_DATES; m++) { | |
243 status = U_ZERO_ERROR; | |
244 TESTZONES[i]->getOffsetFromLocal(MILLIS[m], BasicTimeZone::kStandard
, BasicTimeZone::kStandard, | |
245 rawOffset, dstOffset, status); | |
246 if (U_FAILURE(status)) { | |
247 errln((UnicodeString)"getOffsetFromLocal with kStandard/kStandar
d failed for TESTZONES[" + i + "]"); | |
248 } else if (rawOffset != OFFSETS2[m][0] || dstOffset != OFFSETS2[m][1
]) { | |
249 dateStr.remove(); | |
250 df.format(MILLIS[m], dateStr); | |
251 dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i
+ "] at " | |
252 + dateStr + "(wall/kStandard/kStandard) - Got: " | |
253 + rawOffset + "/" + dstOffset | |
254 + " Expected: " + OFFSETS2[m][0] + "/" + OFFSETS2[m][1])
; | |
255 } | |
256 } | |
257 } | |
258 | |
259 // Test getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t d
uplicatedTimeOpt, | |
260 // int32_t& rawOffset, int32_t& dstOffset, UErroCode& status) | |
261 // with nonExistingTimeOpt=kDaylight/duplicatedTimeOpt=kDaylight | |
262 for (int32_t i = 0; i < NUM_TIMEZONES; i++) { | |
263 for (int m = 0; m < NUM_DATES; m++) { | |
264 status = U_ZERO_ERROR; | |
265 TESTZONES[i]->getOffsetFromLocal(MILLIS[m], BasicTimeZone::kDaylight
, BasicTimeZone::kDaylight, | |
266 rawOffset, dstOffset, status); | |
267 if (U_FAILURE(status)) { | |
268 errln((UnicodeString)"getOffsetFromLocal with kDaylight/kDayligh
t failed for TESTZONES[" + i + "]"); | |
269 } else if (rawOffset != OFFSETS3[m][0] || dstOffset != OFFSETS3[m][1
]) { | |
270 dateStr.remove(); | |
271 df.format(MILLIS[m], dateStr); | |
272 dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i
+ "] at " | |
273 + dateStr + "(wall/kDaylight/kDaylight) - Got: " | |
274 + rawOffset + "/" + dstOffset | |
275 + " Expected: " + OFFSETS3[m][0] + "/" + OFFSETS3[m][1])
; | |
276 } | |
277 } | |
278 } | |
279 | |
280 // Test getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t d
uplicatedTimeOpt, | |
281 // int32_t& rawOffset, int32_t& dstOffset, UErroCode& status) | |
282 // with nonExistingTimeOpt=kFormer/duplicatedTimeOpt=kLatter | |
283 for (int32_t i = 0; i < NUM_TIMEZONES; i++) { | |
284 for (int m = 0; m < NUM_DATES; m++) { | |
285 status = U_ZERO_ERROR; | |
286 TESTZONES[i]->getOffsetFromLocal(MILLIS[m], BasicTimeZone::kFormer,
BasicTimeZone::kLatter, | |
287 rawOffset, dstOffset, status); | |
288 if (U_FAILURE(status)) { | |
289 errln((UnicodeString)"getOffsetFromLocal with kFormer/kLatter fa
iled for TESTZONES[" + i + "]"); | |
290 } else if (rawOffset != OFFSETS2[m][0] || dstOffset != OFFSETS2[m][1
]) { | |
291 dateStr.remove(); | |
292 df.format(MILLIS[m], dateStr); | |
293 dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i
+ "] at " | |
294 + dateStr + "(wall/kFormer/kLatter) - Got: " | |
295 + rawOffset + "/" + dstOffset | |
296 + " Expected: " + OFFSETS2[m][0] + "/" + OFFSETS2[m][1])
; | |
297 } | |
298 } | |
299 } | |
300 | |
301 // Test getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t d
uplicatedTimeOpt, | |
302 // int32_t& rawOffset, int32_t& dstOffset, UErroCode& status) | |
303 // with nonExistingTimeOpt=kLatter/duplicatedTimeOpt=kFormer | |
304 for (int32_t i = 0; i < NUM_TIMEZONES; i++) { | |
305 for (int m = 0; m < NUM_DATES; m++) { | |
306 status = U_ZERO_ERROR; | |
307 TESTZONES[i]->getOffsetFromLocal(MILLIS[m], BasicTimeZone::kLatter,
BasicTimeZone::kFormer, | |
308 rawOffset, dstOffset, status); | |
309 if (U_FAILURE(status)) { | |
310 errln((UnicodeString)"getOffsetFromLocal with kLatter/kFormer fa
iled for TESTZONES[" + i + "]"); | |
311 } else if (rawOffset != OFFSETS3[m][0] || dstOffset != OFFSETS3[m][1
]) { | |
312 dateStr.remove(); | |
313 df.format(MILLIS[m], dateStr); | |
314 dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i
+ "] at " | |
315 + dateStr + "(wall/kLatter/kFormer) - Got: " | |
316 + rawOffset + "/" + dstOffset | |
317 + " Expected: " + OFFSETS3[m][0] + "/" + OFFSETS3[m][1])
; | |
318 } | |
319 } | |
320 } | |
321 | |
322 for (int32_t i = 0; i < NUM_TIMEZONES; i++) { | |
323 delete TESTZONES[i]; | |
324 } | |
325 delete utc; | |
326 delete cal; | |
327 } | |
328 | |
329 #endif /* #if !UCONFIG_NO_FORMATTING */ | |
OLD | NEW |