]>
Commit | Line | Data |
---|---|---|
374ca955 A |
1 | /* |
2 | **************************************************************************** | |
729e4ab9 | 3 | * Copyright (c) 1997-2010, International Business Machines Corporation and * |
374ca955 A |
4 | * others. All Rights Reserved. * |
5 | **************************************************************************** | |
6 | */ | |
7 | ||
8 | #include "unicode/utypes.h" | |
9 | ||
10 | #if !UCONFIG_NO_FORMATTING | |
11 | ||
12 | #include "unicode/utmscale.h" | |
73c04bcf | 13 | #include "unicode/ucal.h" |
374ca955 A |
14 | |
15 | #include "cintltst.h" | |
16 | ||
17 | #include <stdlib.h> | |
18 | #include <time.h> | |
19 | ||
73c04bcf A |
20 | #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) |
21 | ||
374ca955 A |
22 | #define LOOP_COUNT 10000 |
23 | ||
24 | static void TestAPI(void); | |
25 | static void TestData(void); | |
26 | static void TestMonkey(void); | |
73c04bcf | 27 | static void TestDotNet(void); |
374ca955 A |
28 | |
29 | void addUtmsTest(TestNode** root); | |
30 | ||
31 | void addUtmsTest(TestNode** root) | |
32 | { | |
33 | addTest(root, &TestAPI, "tsformat/utmstest/TestAPI"); | |
34 | addTest(root, &TestData, "tsformat/utmstest/TestData"); | |
35 | addTest(root, &TestMonkey, "tsformat/utmstest/TestMonkey"); | |
73c04bcf | 36 | addTest(root, &TestDotNet, "tsformat/utmstest/TestDotNet"); |
374ca955 A |
37 | } |
38 | ||
39 | /** | |
40 | * Return a random int64_t where U_INT64_MIN <= ran <= U_INT64_MAX. | |
41 | */ | |
42 | static uint64_t randomInt64(void) | |
43 | { | |
44 | int64_t ran = 0; | |
45 | int32_t i; | |
46 | static UBool initialized = FALSE; | |
47 | ||
48 | if (!initialized) { | |
49 | srand((unsigned)time(NULL)); | |
50 | initialized = TRUE; | |
51 | } | |
52 | ||
53 | /* Assume rand has at least 12 bits of precision */ | |
54 | for (i = 0; i < sizeof(ran); i += 1) { | |
55 | ((char*)&ran)[i] = (char)((rand() & 0x0FF0) >> 4); | |
56 | } | |
57 | ||
58 | return ran; | |
59 | } | |
60 | ||
61 | static int64_t ranInt; | |
62 | static int64_t ranMin; | |
63 | static int64_t ranMax; | |
64 | ||
65 | static void initRandom(int64_t min, int64_t max) | |
66 | { | |
67 | uint64_t interval = max - min; | |
46f4442e | 68 | |
374ca955 A |
69 | ranMin = min; |
70 | ranMax = max; | |
71 | ranInt = 0; | |
46f4442e A |
72 | |
73 | /* Verify that we don't have a huge interval. */ | |
74 | if (interval < (uint64_t)U_INT64_MAX) { | |
374ca955 A |
75 | ranInt = interval; |
76 | } | |
77 | } | |
78 | ||
79 | static int64_t randomInRange(void) | |
80 | { | |
81 | int64_t value; | |
46f4442e | 82 | |
374ca955 A |
83 | if (ranInt != 0) { |
84 | value = randomInt64() % ranInt; | |
46f4442e | 85 | |
374ca955 A |
86 | if (value < 0) { |
87 | value = -value; | |
88 | } | |
46f4442e | 89 | |
374ca955 A |
90 | value += ranMin; |
91 | } else { | |
92 | do { | |
93 | value = randomInt64(); | |
94 | } while (value < ranMin || value > ranMax); | |
95 | } | |
46f4442e | 96 | |
374ca955 A |
97 | return value; |
98 | } | |
46f4442e A |
99 | |
100 | static void roundTripTest(int64_t value, UDateTimeScale scale) | |
374ca955 A |
101 | { |
102 | UErrorCode status = U_ZERO_ERROR; | |
103 | int64_t rt = utmscale_toInt64(utmscale_fromInt64(value, scale, &status), scale, &status); | |
46f4442e | 104 | |
374ca955 A |
105 | if (rt != value) { |
106 | log_err("Round-trip error: time scale = %d, value = %lld, round-trip = %lld.\n", scale, value, rt); | |
107 | } | |
108 | } | |
109 | ||
46f4442e | 110 | static void toLimitTest(int64_t toLimit, int64_t fromLimit, UDateTimeScale scale) |
374ca955 A |
111 | { |
112 | UErrorCode status = U_ZERO_ERROR; | |
113 | int64_t result = utmscale_toInt64(toLimit, scale, &status); | |
46f4442e | 114 | |
374ca955 A |
115 | if (result != fromLimit) { |
116 | log_err("toLimit failure: scale = %d, toLimit = %lld , utmscale_toInt64(toLimit, scale, &status) = %lld, fromLimit = %lld.\n", | |
117 | scale, toLimit, result, fromLimit); | |
118 | } | |
119 | } | |
120 | ||
46f4442e | 121 | static void epochOffsetTest(int64_t epochOffset, int64_t units, UDateTimeScale scale) |
374ca955 A |
122 | { |
123 | UErrorCode status = U_ZERO_ERROR; | |
124 | int64_t universal = 0; | |
125 | int64_t universalEpoch = epochOffset * units; | |
126 | int64_t local = utmscale_toInt64(universalEpoch, scale, &status); | |
46f4442e | 127 | |
374ca955 A |
128 | if (local != 0) { |
129 | log_err("utmscale_toInt64(epochOffset, scale, &status): scale = %d epochOffset = %lld, result = %lld.\n", scale, epochOffset, local); | |
130 | } | |
46f4442e | 131 | |
374ca955 | 132 | local = utmscale_toInt64(0, scale, &status); |
46f4442e | 133 | |
374ca955 A |
134 | if (local != -epochOffset) { |
135 | log_err("utmscale_toInt64(0, scale): scale = %d, result = %lld.\n", scale, local); | |
136 | } | |
46f4442e | 137 | |
374ca955 | 138 | universal = utmscale_fromInt64(-epochOffset, scale, &status); |
46f4442e | 139 | |
374ca955 A |
140 | if (universal != 0) { |
141 | log_err("from(-epochOffest, scale): scale = %d, epochOffset = %lld, result = %lld.\n", scale, epochOffset, universal); | |
142 | } | |
46f4442e | 143 | |
374ca955 | 144 | universal = utmscale_fromInt64(0, scale, &status); |
46f4442e | 145 | |
374ca955 A |
146 | if (universal != universalEpoch) { |
147 | log_err("utmscale_fromInt64(0, scale): scale = %d, result = %lld.\n", scale, universal); | |
148 | } | |
149 | } | |
150 | ||
151 | static void TestEpochOffsets(void) | |
152 | { | |
153 | UErrorCode status = U_ZERO_ERROR; | |
154 | int32_t scale; | |
155 | ||
156 | for (scale = 0; scale < UDTS_MAX_SCALE; scale += 1) { | |
46f4442e A |
157 | int64_t units = utmscale_getTimeScaleValue((UDateTimeScale)scale, UTSV_UNITS_VALUE, &status); |
158 | int64_t epochOffset = utmscale_getTimeScaleValue((UDateTimeScale)scale, UTSV_EPOCH_OFFSET_VALUE, &status); | |
159 | ||
160 | epochOffsetTest(epochOffset, units, (UDateTimeScale)scale); | |
374ca955 A |
161 | } |
162 | } | |
163 | ||
164 | static void TestFromLimits(void) | |
165 | { | |
166 | UErrorCode status = U_ZERO_ERROR; | |
167 | int32_t scale; | |
168 | ||
169 | for (scale = 0; scale < UDTS_MAX_SCALE; scale += 1) { | |
46f4442e A |
170 | int64_t fromMin = utmscale_getTimeScaleValue((UDateTimeScale)scale, UTSV_FROM_MIN_VALUE, &status); |
171 | int64_t fromMax = utmscale_getTimeScaleValue((UDateTimeScale)scale, UTSV_FROM_MAX_VALUE, &status); | |
172 | ||
173 | roundTripTest(fromMin, (UDateTimeScale)scale); | |
174 | roundTripTest(fromMax, (UDateTimeScale)scale); | |
374ca955 A |
175 | } |
176 | } | |
177 | ||
178 | static void TestToLimits(void) | |
179 | { | |
180 | UErrorCode status = U_ZERO_ERROR; | |
181 | int32_t scale; | |
182 | ||
183 | for (scale = 0; scale < UDTS_MAX_SCALE; scale += 1) { | |
46f4442e A |
184 | int64_t fromMin = utmscale_getTimeScaleValue((UDateTimeScale)scale, UTSV_FROM_MIN_VALUE, &status); |
185 | int64_t fromMax = utmscale_getTimeScaleValue((UDateTimeScale)scale, UTSV_FROM_MAX_VALUE, &status); | |
186 | int64_t toMin = utmscale_getTimeScaleValue((UDateTimeScale)scale, UTSV_TO_MIN_VALUE, &status); | |
187 | int64_t toMax = utmscale_getTimeScaleValue((UDateTimeScale)scale, UTSV_TO_MAX_VALUE, &status); | |
188 | ||
189 | toLimitTest(toMin, fromMin, (UDateTimeScale)scale); | |
190 | toLimitTest(toMax, fromMax, (UDateTimeScale)scale); | |
374ca955 A |
191 | } |
192 | } | |
193 | ||
194 | static void TestFromInt64(void) | |
195 | { | |
196 | int32_t scale; | |
197 | int64_t result; | |
198 | UErrorCode status = U_ZERO_ERROR; | |
46f4442e | 199 | |
374ca955 A |
200 | result = utmscale_fromInt64(0, -1, &status); |
201 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { | |
202 | log_err("utmscale_fromInt64(0, -1, status) did not set status to U_ILLEGAL_ARGUMENT_ERROR.\n"); | |
203 | } | |
46f4442e | 204 | |
374ca955 A |
205 | for (scale = 0; scale < UDTS_MAX_SCALE; scale += 1) { |
206 | int64_t fromMin, fromMax; | |
46f4442e | 207 | |
374ca955 | 208 | status = U_ZERO_ERROR; |
46f4442e A |
209 | fromMin = utmscale_getTimeScaleValue((UDateTimeScale)scale, UTSV_FROM_MIN_VALUE, &status); |
210 | fromMax = utmscale_getTimeScaleValue((UDateTimeScale)scale, UTSV_FROM_MAX_VALUE, &status); | |
211 | ||
374ca955 | 212 | status = U_ZERO_ERROR; |
46f4442e | 213 | result = utmscale_fromInt64(0, (UDateTimeScale)scale, &status); |
374ca955 A |
214 | if (status == U_ILLEGAL_ARGUMENT_ERROR) { |
215 | log_err("utmscale_fromInt64(0, %d, &status) generated U_ILLEGAL_ARGUMENT_ERROR.\n", scale); | |
216 | } | |
46f4442e | 217 | |
374ca955 | 218 | status = U_ZERO_ERROR; |
46f4442e | 219 | result = utmscale_fromInt64(fromMin, (UDateTimeScale)scale, &status); |
374ca955 A |
220 | if (status == U_ILLEGAL_ARGUMENT_ERROR) { |
221 | log_err("utmscale_fromInt64(fromMin, %d, &status) generated U_ILLEGAL_ARGUMENT_ERROR.\n", scale); | |
222 | } | |
46f4442e A |
223 | |
224 | if (fromMin > U_INT64_MIN) { | |
374ca955 | 225 | status = U_ZERO_ERROR; |
46f4442e | 226 | result = utmscale_fromInt64(fromMin - 1, (UDateTimeScale)scale, &status); |
374ca955 A |
227 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { |
228 | log_err("utmscale_fromInt64(fromMin - 1, %d, &status) did not generate U_ILLEGAL_ARGUMENT_ERROR.\n", scale); | |
229 | } | |
230 | } | |
46f4442e | 231 | |
374ca955 | 232 | status = U_ZERO_ERROR; |
46f4442e | 233 | result = utmscale_fromInt64(fromMax, (UDateTimeScale)scale, &status); |
374ca955 A |
234 | if (status == U_ILLEGAL_ARGUMENT_ERROR) { |
235 | log_err("utmscale_fromInt64(fromMax, %d, &status) generated U_ILLEGAL_ARGUMENT_ERROR.\n", scale); | |
236 | } | |
46f4442e | 237 | |
374ca955 A |
238 | if (fromMax < U_INT64_MAX) { |
239 | status = U_ZERO_ERROR; | |
46f4442e | 240 | result = utmscale_fromInt64(fromMax + 1, (UDateTimeScale)scale, &status); |
374ca955 A |
241 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { |
242 | log_err("utmscale_fromInt64(fromMax + 1, %d, &status) didn't generate U_ILLEGAL_ARGUMENT_ERROR.\n", scale); | |
243 | } | |
244 | } | |
245 | } | |
46f4442e | 246 | |
374ca955 A |
247 | status = U_ZERO_ERROR; |
248 | result = utmscale_fromInt64(0, UDTS_MAX_SCALE, &status); | |
249 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { | |
250 | log_err("utmscale_fromInt64(0, UDTS_MAX_SCALE, &status) did not generate U_ILLEGAL_ARGUMENT_ERROR.\n"); | |
251 | } | |
252 | } | |
253 | ||
254 | static void TestToInt64(void) | |
255 | { | |
256 | int32_t scale; | |
257 | int64_t result; | |
258 | UErrorCode status = U_ZERO_ERROR; | |
46f4442e | 259 | |
374ca955 A |
260 | result = utmscale_toInt64(0, -1, &status); |
261 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { | |
262 | log_err("utmscale_toInt64(0, -1, &status) did not generate U_ILLEGAL_ARGUMENT_ERROR.\n"); | |
263 | } | |
46f4442e | 264 | |
374ca955 A |
265 | for (scale = 0; scale < UDTS_MAX_SCALE; scale += 1) { |
266 | int64_t toMin, toMax; | |
46f4442e | 267 | |
374ca955 | 268 | status = U_ZERO_ERROR; |
46f4442e A |
269 | toMin = utmscale_getTimeScaleValue((UDateTimeScale)scale, UTSV_TO_MIN_VALUE, &status); |
270 | toMax = utmscale_getTimeScaleValue((UDateTimeScale)scale, UTSV_TO_MAX_VALUE, &status); | |
374ca955 A |
271 | |
272 | status = U_ZERO_ERROR; | |
46f4442e | 273 | result = utmscale_toInt64(0, (UDateTimeScale)scale, &status); |
374ca955 A |
274 | if (status == U_ILLEGAL_ARGUMENT_ERROR) { |
275 | log_err("utmscale_toInt64(0, %d, &status) generated U_ILLEGAL_ARGUMENT_ERROR.\n", scale); | |
276 | } | |
46f4442e | 277 | |
374ca955 | 278 | status = U_ZERO_ERROR; |
46f4442e | 279 | result = utmscale_toInt64(toMin, (UDateTimeScale)scale, &status); |
374ca955 A |
280 | if (status == U_ILLEGAL_ARGUMENT_ERROR) { |
281 | log_err("utmscale_toInt64(toMin, %d, &status) generated U_ILLEGAL_ARGUMENT_ERROR.\n", scale); | |
282 | } | |
46f4442e | 283 | |
374ca955 A |
284 | if (toMin > U_INT64_MIN) { |
285 | status = U_ZERO_ERROR; | |
46f4442e | 286 | result = utmscale_toInt64(toMin - 1, (UDateTimeScale)scale, &status); |
374ca955 A |
287 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { |
288 | log_err("utmscale_toInt64(toMin - 1, %d, &status) did not generate U_ILLEGAL_ARGUMENT_ERROR.\n", scale); | |
289 | } | |
290 | } | |
291 | ||
46f4442e | 292 | |
374ca955 | 293 | status = U_ZERO_ERROR; |
46f4442e | 294 | result = utmscale_toInt64(toMax, (UDateTimeScale)scale, &status); |
374ca955 A |
295 | if (status == U_ILLEGAL_ARGUMENT_ERROR) { |
296 | log_err("utmscale_toInt64(toMax, %d, &status) generated U_ILLEGAL_ARGUMENT_ERROR.\n", scale); | |
297 | } | |
46f4442e | 298 | |
374ca955 A |
299 | if (toMax < U_INT64_MAX) { |
300 | status = U_ZERO_ERROR; | |
46f4442e | 301 | result = utmscale_toInt64(toMax + 1, (UDateTimeScale)scale, &status); |
374ca955 A |
302 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { |
303 | log_err("utmscale_toInt64(toMax + 1, %d, &status) did not generate U_ILLEGAL_ARGUMENT_ERROR.\n", scale); | |
304 | } | |
305 | } | |
306 | } | |
46f4442e | 307 | |
374ca955 A |
308 | status = U_ZERO_ERROR; |
309 | result = utmscale_toInt64(0, UDTS_MAX_SCALE, &status); | |
310 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { | |
311 | log_err("utmscale_toInt64(0, UDTS_MAX_SCALE, &status) did not generate U_ILLEGAL_ARGUMENT_ERROR.\n"); | |
312 | } | |
313 | } | |
314 | ||
315 | static void TestAPI(void) | |
316 | { | |
317 | TestFromInt64(); | |
318 | TestToInt64(); | |
319 | } | |
320 | ||
321 | static void TestData(void) | |
322 | { | |
323 | TestEpochOffsets(); | |
324 | TestFromLimits(); | |
325 | TestToLimits(); | |
326 | } | |
327 | ||
328 | static void TestMonkey(void) | |
329 | { | |
330 | int32_t scale; | |
331 | UErrorCode status = U_ZERO_ERROR; | |
46f4442e | 332 | |
374ca955 | 333 | for (scale = 0; scale < UDTS_MAX_SCALE; scale += 1) { |
46f4442e A |
334 | int64_t fromMin = utmscale_getTimeScaleValue((UDateTimeScale)scale, UTSV_FROM_MIN_VALUE, &status); |
335 | int64_t fromMax = utmscale_getTimeScaleValue((UDateTimeScale)scale, UTSV_FROM_MAX_VALUE, &status); | |
374ca955 | 336 | int32_t i; |
46f4442e | 337 | |
374ca955 | 338 | initRandom(fromMin, fromMax); |
46f4442e | 339 | |
374ca955 A |
340 | for (i = 0; i < LOOP_COUNT; i += 1) { |
341 | int64_t value = randomInRange(); | |
46f4442e A |
342 | |
343 | roundTripTest(value, (UDateTimeScale)scale); | |
374ca955 A |
344 | } |
345 | } | |
346 | } | |
347 | ||
73c04bcf A |
348 | struct DotNetDateTimeTicks { |
349 | int32_t year; | |
350 | int32_t month; | |
351 | int32_t day; | |
352 | int64_t ticks; | |
353 | }; | |
354 | typedef struct DotNetDateTimeTicks DotNetDateTimeTicks; | |
355 | ||
356 | /* | |
357 | * This data was generated by C++.Net code like | |
358 | * Console::WriteLine(L" {{ {0}, 1, 1, INT64_C({1}) }},", year, DateTime(year, 1, 1).Ticks); | |
359 | * with the DateTime constructor taking int values for year, month, and date. | |
360 | */ | |
361 | static const DotNetDateTimeTicks dotNetDateTimeTicks[]={ | |
362 | /* year, month, day, ticks */ | |
363 | { 100, 1, 1, INT64_C(31241376000000000) }, | |
364 | { 100, 3, 1, INT64_C(31292352000000000) }, | |
365 | { 200, 1, 1, INT64_C(62798112000000000) }, | |
366 | { 200, 3, 1, INT64_C(62849088000000000) }, | |
367 | { 300, 1, 1, INT64_C(94354848000000000) }, | |
368 | { 300, 3, 1, INT64_C(94405824000000000) }, | |
369 | { 400, 1, 1, INT64_C(125911584000000000) }, | |
370 | { 400, 3, 1, INT64_C(125963424000000000) }, | |
371 | { 500, 1, 1, INT64_C(157469184000000000) }, | |
372 | { 500, 3, 1, INT64_C(157520160000000000) }, | |
373 | { 600, 1, 1, INT64_C(189025920000000000) }, | |
374 | { 600, 3, 1, INT64_C(189076896000000000) }, | |
375 | { 700, 1, 1, INT64_C(220582656000000000) }, | |
376 | { 700, 3, 1, INT64_C(220633632000000000) }, | |
377 | { 800, 1, 1, INT64_C(252139392000000000) }, | |
378 | { 800, 3, 1, INT64_C(252191232000000000) }, | |
379 | { 900, 1, 1, INT64_C(283696992000000000) }, | |
380 | { 900, 3, 1, INT64_C(283747968000000000) }, | |
381 | { 1000, 1, 1, INT64_C(315253728000000000) }, | |
382 | { 1000, 3, 1, INT64_C(315304704000000000) }, | |
383 | { 1100, 1, 1, INT64_C(346810464000000000) }, | |
384 | { 1100, 3, 1, INT64_C(346861440000000000) }, | |
385 | { 1200, 1, 1, INT64_C(378367200000000000) }, | |
386 | { 1200, 3, 1, INT64_C(378419040000000000) }, | |
387 | { 1300, 1, 1, INT64_C(409924800000000000) }, | |
388 | { 1300, 3, 1, INT64_C(409975776000000000) }, | |
389 | { 1400, 1, 1, INT64_C(441481536000000000) }, | |
390 | { 1400, 3, 1, INT64_C(441532512000000000) }, | |
391 | { 1500, 1, 1, INT64_C(473038272000000000) }, | |
392 | { 1500, 3, 1, INT64_C(473089248000000000) }, | |
393 | { 1600, 1, 1, INT64_C(504595008000000000) }, | |
394 | { 1600, 3, 1, INT64_C(504646848000000000) }, | |
395 | { 1700, 1, 1, INT64_C(536152608000000000) }, | |
396 | { 1700, 3, 1, INT64_C(536203584000000000) }, | |
397 | { 1800, 1, 1, INT64_C(567709344000000000) }, | |
398 | { 1800, 3, 1, INT64_C(567760320000000000) }, | |
399 | { 1900, 1, 1, INT64_C(599266080000000000) }, | |
400 | { 1900, 3, 1, INT64_C(599317056000000000) }, | |
401 | { 2000, 1, 1, INT64_C(630822816000000000) }, | |
402 | { 2000, 3, 1, INT64_C(630874656000000000) }, | |
403 | { 2100, 1, 1, INT64_C(662380416000000000) }, | |
404 | { 2100, 3, 1, INT64_C(662431392000000000) }, | |
405 | { 2200, 1, 1, INT64_C(693937152000000000) }, | |
406 | { 2200, 3, 1, INT64_C(693988128000000000) }, | |
407 | { 2300, 1, 1, INT64_C(725493888000000000) }, | |
408 | { 2300, 3, 1, INT64_C(725544864000000000) }, | |
409 | { 2400, 1, 1, INT64_C(757050624000000000) }, | |
410 | { 2400, 3, 1, INT64_C(757102464000000000) }, | |
411 | { 2500, 1, 1, INT64_C(788608224000000000) }, | |
412 | { 2500, 3, 1, INT64_C(788659200000000000) }, | |
413 | { 2600, 1, 1, INT64_C(820164960000000000) }, | |
414 | { 2600, 3, 1, INT64_C(820215936000000000) }, | |
415 | { 2700, 1, 1, INT64_C(851721696000000000) }, | |
416 | { 2700, 3, 1, INT64_C(851772672000000000) }, | |
417 | { 2800, 1, 1, INT64_C(883278432000000000) }, | |
418 | { 2800, 3, 1, INT64_C(883330272000000000) }, | |
419 | { 2900, 1, 1, INT64_C(914836032000000000) }, | |
420 | { 2900, 3, 1, INT64_C(914887008000000000) }, | |
421 | { 3000, 1, 1, INT64_C(946392768000000000) }, | |
422 | { 3000, 3, 1, INT64_C(946443744000000000) }, | |
423 | { 1, 1, 1, INT64_C(0) }, | |
424 | { 1601, 1, 1, INT64_C(504911232000000000) }, | |
425 | { 1899, 12, 31, INT64_C(599265216000000000) }, | |
426 | { 1904, 1, 1, INT64_C(600527520000000000) }, | |
427 | { 1970, 1, 1, INT64_C(621355968000000000) }, | |
428 | { 2001, 1, 1, INT64_C(631139040000000000) }, | |
429 | { 9900, 3, 1, INT64_C(3123873216000000000) }, | |
430 | { 9999, 12, 31, INT64_C(3155378112000000000) } | |
431 | }; | |
432 | ||
433 | /* | |
434 | * ICU's Universal Time Scale is designed to be tick-for-tick compatible with | |
435 | * .Net System.DateTime. Verify that this is so for the | |
436 | * .Net-supported date range (years 1-9999 AD). | |
437 | * This requires a proleptic Gregorian calendar because that's what .Net uses. | |
438 | * Proleptic: No Julian/Gregorian switchover, or a switchover before | |
439 | * any date that we test, that is, before 0001 AD. | |
440 | */ | |
441 | static void | |
442 | TestDotNet() { | |
443 | static const UChar utc[] = { 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0 }; /* "Etc/GMT" */ | |
444 | const int32_t dayMillis = 86400 * INT64_C(1000); /* 1 day = 86400 seconds */ | |
445 | const int64_t dayTicks = 86400 * INT64_C(10000000); | |
446 | const DotNetDateTimeTicks *dt; | |
447 | UCalendar *cal; | |
448 | UErrorCode errorCode; | |
449 | UDate icuDate; | |
450 | int64_t ticks, millis; | |
451 | int32_t i; | |
452 | ||
453 | /* Open a proleptic Gregorian calendar. */ | |
454 | errorCode = U_ZERO_ERROR; | |
455 | cal = ucal_open(utc, -1, "", UCAL_GREGORIAN, &errorCode); | |
456 | ucal_setGregorianChange(cal, -1000000 * (dayMillis * (UDate)1), &errorCode); | |
457 | if(U_FAILURE(errorCode)) { | |
729e4ab9 | 458 | log_data_err("ucal_open(UTC/proleptic Gregorian) failed: %s - (Are you missing data?)\n", u_errorName(errorCode)); |
73c04bcf A |
459 | ucal_close(cal); |
460 | return; | |
461 | } | |
462 | for(i = 0; i < LENGTHOF(dotNetDateTimeTicks); ++i) { | |
463 | /* Test conversion from .Net/Universal time to ICU time. */ | |
464 | dt = dotNetDateTimeTicks + i; | |
465 | millis = utmscale_toInt64(dt->ticks, UDTS_ICU4C_TIME, &errorCode); | |
466 | ucal_clear(cal); | |
467 | ucal_setDate(cal, dt->year, dt->month - 1, dt->day, &errorCode); /* Java & ICU use January = month 0. */ | |
468 | icuDate = ucal_getMillis(cal, &errorCode); | |
469 | if(millis != icuDate) { | |
470 | /* Print days not millis to stay within printf() range. */ | |
471 | log_err("utmscale_toInt64(ticks[%d], ICU4C)=%dd != %dd=ucal_getMillis(%04d-%02d-%02d)\n", | |
472 | (int)i, (int)(millis/dayMillis), (int)(icuDate/dayMillis), (int)dt->year, (int)dt->month, (int)dt->day); | |
473 | } | |
474 | ||
475 | /* Test conversion from ICU time to .Net/Universal time. */ | |
476 | ticks = utmscale_fromInt64((int64_t)icuDate, UDTS_ICU4C_TIME, &errorCode); | |
477 | if(ticks != dt->ticks) { | |
478 | /* Print days not ticks to stay within printf() range. */ | |
479 | log_err("utmscale_fromInt64(date[%d], ICU4C)=%dd != %dd=.Net System.DateTime(%04d-%02d-%02d).Ticks\n", | |
480 | (int)i, (int)(ticks/dayTicks), (int)(dt->ticks/dayTicks), (int)dt->year, (int)dt->month, (int)dt->day); | |
481 | } | |
482 | } | |
483 | ||
484 | ucal_close(cal); | |
485 | } | |
486 | ||
374ca955 | 487 | #endif /* #if !UCONFIG_NO_FORMATTING */ |