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