]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/intltest/tsdate.cpp
ICU-59117.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / tsdate.cpp
CommitLineData
f3c0d7a5
A
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
374ca955 3/***********************************************************************
729e4ab9 4 * Copyright (c) 1997-2009, International Business Machines Corporation
374ca955
A
5 * and others. All Rights Reserved.
6 ***********************************************************************/
b75a7d8f
A
7
8#include "unicode/utypes.h"
9
10#if !UCONFIG_NO_FORMATTING
11
12#include "unicode/datefmt.h"
13#include "unicode/smpdtfmt.h"
14#include "tsdate.h"
374ca955 15#include "putilimp.h"
b75a7d8f
A
16
17#include <float.h>
18#include <stdlib.h>
73c04bcf 19#include <math.h>
b75a7d8f
A
20
21const double IntlTestDateFormat::ONEYEAR = 365.25 * ONEDAY; // Approximate
22
374ca955
A
23IntlTestDateFormat::~IntlTestDateFormat() {}
24
b75a7d8f
A
25/**
26 * This test does round-trip testing (format -> parse -> format -> parse -> etc.) of
27 * DateFormat.
28 */
29// par is ignored throughout this file
30void IntlTestDateFormat::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
31{
32 if (exec) logln("TestSuite DateFormat");
33 switch (index) {
34 case 0: name = "GenericTest";
35 if (exec) {
36 logln(name);
37 fFormat = DateFormat::createInstance();
38 fTestName = "createInstance";
39 fLimit = 3;
40 testFormat(/* par */);
41 }
42 break;
43 case 1: name = "DefaultLocale";
44 if (exec) {
45 logln(name);
46 testLocale(/*par, */Locale::getDefault(), "Default Locale");
47 }
48 break;
49
50 case 2: name = "TestAvailableLocales";
51 if (exec) {
52 logln(name);
53 testAvailableLocales(/* par */);
54 }
55 break;
56
57 case 3: name = "MonsterTest";
58 if (exec) {
59 logln(name);
60 monsterTest(/*par*/);
61 }
62 break;
63
64 default: name = ""; break;
65 }
66}
67
68void
69IntlTestDateFormat::testLocale(/*char* par, */const Locale& locale, const UnicodeString& localeName)
70{
71 DateFormat::EStyle timeStyle, dateStyle;
72
73 // For patterns including only time information and a timezone, it may take
74 // up to three iterations, since the timezone may shift as the year number
75 // is determined. For other patterns, 2 iterations should suffice.
76 fLimit = 3;
77
78 for(timeStyle = (DateFormat::EStyle)0;
79 timeStyle < (DateFormat::EStyle)4;
80 timeStyle = (DateFormat::EStyle) (timeStyle+1))
81 {
82 fTestName = (UnicodeString) "Time test " + (int32_t) timeStyle + " (" + localeName + ")";
83 fFormat = DateFormat::createTimeInstance(timeStyle, locale);
84 testFormat(/* par */);
85 }
86
87 fLimit = 2;
88
89 for(dateStyle = (DateFormat::EStyle)0;
90 dateStyle < (DateFormat::EStyle)4;
91 dateStyle = (DateFormat::EStyle) (dateStyle+1))
92 {
93 fTestName = (UnicodeString) "Date test " + (int32_t) dateStyle + " (" + localeName + ")";
94 fFormat = DateFormat::createDateInstance(dateStyle, locale);
95 testFormat(/* par */);
96 }
97
98 for(dateStyle = (DateFormat::EStyle)0;
99 dateStyle < (DateFormat::EStyle)4;
100 dateStyle = (DateFormat::EStyle) (dateStyle+1))
101 {
102 for(timeStyle = (DateFormat::EStyle)0;
103 timeStyle < (DateFormat::EStyle)4;
104 timeStyle = (DateFormat::EStyle) (timeStyle+1))
105 {
106 fTestName = (UnicodeString) "DateTime test " + (int32_t) dateStyle + "/" + (int32_t) timeStyle + " (" + localeName + ")";
107 fFormat = DateFormat::createDateTimeInstance(dateStyle, timeStyle, locale);
108 testFormat(/* par */);
109 }
110 }
111}
112
113void IntlTestDateFormat::testFormat(/* char* par */)
114{
115 if (fFormat == 0)
116 {
729e4ab9 117 dataerrln("FAIL: DateFormat creation failed");
b75a7d8f
A
118 return;
119 }
120
121 describeTest();
122
123 UDate now = Calendar::getNow();
124 tryDate(0);
125 tryDate(1278161801778.0);
126 tryDate(5264498352317.0); // Sunday, October 28, 2136 8:39:12 AM PST
127 tryDate(9516987689250.0); // In the year 2271
128 tryDate(now);
129 // Shift 6 months into the future, AT THE SAME TIME OF DAY.
130 // This will test the DST handling.
131 tryDate(now + 6.0*30*ONEDAY);
132
133 UDate limit = now * 10; // Arbitrary limit
134 for (int32_t i=0; i<3; ++i)
135 tryDate(uprv_floor(randDouble() * limit));
136
137 delete fFormat;
138}
139
140void
141IntlTestDateFormat::describeTest()
142{
143 // Assume it's a SimpleDateFormat and get some info
144 SimpleDateFormat *s = (SimpleDateFormat*)fFormat;
145 UnicodeString str;
146 logln(fTestName + " Pattern " + s->toPattern(str));
147}
148
149void IntlTestDateFormat::tryDate(UDate theDate)
150{
151 const int32_t DEPTH = 10;
152 UDate date[DEPTH];
153 UnicodeString string[DEPTH];
154
155 int32_t dateMatch = 0;
156 int32_t stringMatch = 0;
157 UBool dump = FALSE;
374ca955
A
158#if defined (U_CAL_DEBUG)
159 dump = TRUE;
160#endif
b75a7d8f
A
161 int32_t i;
162
163 date[0] = theDate;
164 fFormat->format(theDate, string[0]);
165
166 for (i=1; i<DEPTH; ++i)
167 {
168 UErrorCode status = U_ZERO_ERROR;
169 date[i] = fFormat->parse(string[i-1], status);
170 if (U_FAILURE(status))
171 {
172 describeTest();
173 errln("**** FAIL: Parse of " + prettify(string[i-1], FALSE) + " failed.");
174 dump = TRUE;
175 break;
176 }
177 fFormat->format(date[i], string[i]);
178 if (dateMatch == 0 && date[i] == date[i-1])
179 dateMatch = i;
180 else if (dateMatch > 0 && date[i] != date[i-1])
181 {
182 describeTest();
183 errln("**** FAIL: Date mismatch after match for " + string[i]);
184 dump = TRUE;
185 break;
186 }
187 if (stringMatch == 0 && string[i] == string[i-1])
188 stringMatch = i;
189 else if (stringMatch > 0 && string[i] != string[i-1])
190 {
191 describeTest();
192 errln("**** FAIL: String mismatch after match for " + string[i]);
193 dump = TRUE;
194 break;
195 }
196 if (dateMatch > 0 && stringMatch > 0)
197 break;
198 }
199 if (i == DEPTH)
200 --i;
201
202 if (stringMatch > fLimit || dateMatch > fLimit)
203 {
204 describeTest();
205 errln((UnicodeString)"**** FAIL: No string and/or date match within " + fLimit
206 + " iterations for the Date " + string[0] + "\t(" + theDate + ").");
207 dump = TRUE;
208 }
209
210 if (dump)
211 {
212 for (int32_t k=0; k<=i; ++k)
213 {
214 logln((UnicodeString)"" + k + ": " + date[k] + " F> " +
215 string[k] + " P> ");
216 }
217 }
218}
73c04bcf 219
b75a7d8f
A
220// Return a random double from 0.01 to 1, inclusive
221double IntlTestDateFormat::randDouble()
222{
223 // Assume 8-bit (or larger) rand values. Also assume
224 // that the system rand() function is very poor, which it always is.
225 double d=0.0;
226 uint32_t i;
227 char* poke = (char*)&d;
228 do {
229 do {
230 for (i=0; i < sizeof(double); ++i)
231 {
232 poke[i] = (char)(rand() & 0xFF);
233 }
234 } while (uprv_isNaN(d) || uprv_isInfinite(d));
235
236 if (d < 0.0)
237 d = -d;
238 if (d > 0.0)
239 {
73c04bcf 240 double e = uprv_floor(log10(d));
b75a7d8f
A
241 if (e < -2.0)
242 d *= uprv_pow10((int32_t)(-e-2));
243 else if (e > -1.0)
244 d /= uprv_pow10((int32_t)(e+1));
245 }
246 // While this is not a real normalized number make another one.
247 } while (uprv_isNaN(d) || uprv_isInfinite(d)
248 || !((-DBL_MAX < d && d < DBL_MAX) || (d < -DBL_MIN && DBL_MIN < d)));
249 return d;
250}
251
252void IntlTestDateFormat::testAvailableLocales(/* char* par */)
253{
254 int32_t count = 0;
255 const Locale* locales = DateFormat::getAvailableLocales(count);
256 logln((UnicodeString)"" + count + " available locales");
257 if (locales && count)
258 {
259 UnicodeString name;
260 UnicodeString all;
261 for (int32_t i=0; i<count; ++i)
262 {
263 if (i!=0) all += ", ";
264 all += locales[i].getName();
265 }
266 logln(all);
267 }
729e4ab9 268 else dataerrln((UnicodeString)"**** FAIL: Zero available locales or null array pointer");
b75a7d8f
A
269}
270
271void IntlTestDateFormat::monsterTest(/*char *par*/)
272{
273 int32_t count;
274 const Locale* locales = DateFormat::getAvailableLocales(count);
275 if (locales && count)
276 {
277 if (quick && count > 3) {
278 logln("quick test: testing just 3 locales!");
279 count = 3;
280 }
281 for (int32_t i=0; i<count; ++i)
282 {
283 UnicodeString name = UnicodeString(locales[i].getName(), "");
284 logln((UnicodeString)"Testing " + name + "...");
285 testLocale(/*par, */locales[i], name);
286 }
287 }
288}
289
290#endif /* #if !UCONFIG_NO_FORMATTING */