1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /***********************************************************************
4  * Copyright (c) 1997-2011, International Business Machines Corporation
5  * and others. All Rights Reserved.
6  ***********************************************************************/
7 
8 #include "unicode/utypes.h"
9 
10 #if !UCONFIG_NO_FORMATTING
11 
12 #include "miscdtfm.h"
13 
14 #include "unicode/format.h"
15 #include "unicode/decimfmt.h"
16 #include "unicode/datefmt.h"
17 #include "unicode/smpdtfmt.h"
18 #include "unicode/dtfmtsym.h"
19 #include "unicode/locid.h"
20 #include "unicode/msgfmt.h"
21 #include "unicode/numfmt.h"
22 #include "unicode/choicfmt.h"
23 #include "unicode/gregocal.h"
24 
25 // *****************************************************************************
26 // class DateFormatMiscTests
27 // *****************************************************************************
28 
29 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break;
30 
31 void
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)32 DateFormatMiscTests::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
33 {
34     // if (exec) logln((UnicodeString)"TestSuite DateFormatMiscTests");
35     switch (index) {
36         CASE(0, test4097450)
37         CASE(1, test4099975)
38         CASE(2, test4117335)
39 
40         default: name = ""; break;
41     }
42 }
43 
44 UBool
failure(UErrorCode status,const char * msg)45 DateFormatMiscTests::failure(UErrorCode status, const char* msg)
46 {
47     if(U_FAILURE(status)) {
48         errcheckln(status, UnicodeString("FAIL: ") + msg + " failed, error " + u_errorName(status));
49         return TRUE;
50     }
51 
52     return FALSE;
53 }
54 
55 /*
56  * @bug 4097450
57  */
58 void
test4097450()59 DateFormatMiscTests::test4097450()
60 {
61     //
62     // Date parse requiring 4 digit year.
63     //
64     UnicodeString  dstring [] = {
65         UnicodeString("97"),
66         UnicodeString("1997"),
67         UnicodeString("97"),
68         UnicodeString("1997"),
69         UnicodeString("01"),
70         UnicodeString("2001"),
71         UnicodeString("01"),
72         UnicodeString("2001"),
73         UnicodeString("1"),
74         UnicodeString("1"),
75         UnicodeString("11"),
76         UnicodeString("11"),
77         UnicodeString("111"),
78         UnicodeString("111")
79     };
80 
81     UnicodeString dformat [] = {
82         UnicodeString("yy"),
83         UnicodeString("yy"),
84         UnicodeString("yyyy"),
85         UnicodeString("yyyy"),
86         UnicodeString("yy"),
87         UnicodeString("yy"),
88         UnicodeString("yyyy"),
89         UnicodeString("yyyy"),
90         UnicodeString("yy"),
91         UnicodeString("yyyy"),
92         UnicodeString("yy"),
93         UnicodeString("yyyy"),
94         UnicodeString("yy"),
95         UnicodeString("yyyy")
96     };
97 
98 /*    UBool dresult [] = {
99         TRUE,
100         FALSE,
101         FALSE,
102         TRUE,
103         TRUE,
104         FALSE,
105         FALSE,
106         TRUE,
107         FALSE,
108         FALSE,
109         TRUE,
110         FALSE,
111         FALSE,
112         FALSE
113     };*/
114 
115     UErrorCode status = U_ZERO_ERROR;
116     LocalPointer<SimpleDateFormat> formatter;
117     SimpleDateFormat resultFormatter((UnicodeString)u"yyyy", status);
118     if (U_FAILURE(status)) {
119         dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
120         return;
121     }
122 
123     logln("Format\tSource\tResult");
124     logln("-------\t-------\t-------");
125     for (int i = 0; i < 14/*dstring.length*/; i++)
126     {
127         log(dformat[i] + "\t" + dstring[i] + "\t");
128         formatter.adoptInstead(new SimpleDateFormat(dformat[i], status));
129         if(failure(status, "new SimpleDateFormat")) return;
130         //try {
131         UnicodeString str;
132         FieldPosition pos(FieldPosition::DONT_CARE);
133         logln(resultFormatter.format(formatter->parse(dstring[i], status), str, pos));
134         failure(status, "resultFormatter.format");
135             //if ( !dresult[i] ) System.out.print("   <-- error!");
136         /*}
137         catch (ParseException exception) {
138             //if ( dresult[i] ) System.out.print("   <-- error!");
139             System.out.print("exception --> " + exception);
140         }*/
141         logln();
142     }
143 }
144 
145 /*
146  * @bug 4099975
147  */
148 void
test4099975()149 DateFormatMiscTests::test4099975()
150 {
151     /**
152      * Test Constructor SimpleDateFormat::SimpleDateFormat (const UnicodeString & pattern,
153      *                                    const DateFormatSymbols & formatData, UErrorCode & status )
154      * The DateFormatSymbols object is NOT adopted; Modifying the original DateFormatSymbols
155      * should not change the SimpleDateFormat's behavior.
156      */
157     UDate d = Calendar::getNow();
158     {
159         UErrorCode status = U_ZERO_ERROR;
160         DateFormatSymbols* symbols = new DateFormatSymbols(Locale::getUS(), status);
161         if (U_FAILURE(status)) {
162             dataerrln("Unable to create DateFormatSymbols - %s", u_errorName(status));
163             return;
164         }
165         SimpleDateFormat *df = new SimpleDateFormat(UnicodeString("E hh:mm"), *symbols, status);
166         if(failure(status, "new SimpleDateFormat")) return;
167         UnicodeString format0;
168         format0 = df->format(d, format0);
169         UnicodeString localizedPattern0;
170         localizedPattern0 = df->toLocalizedPattern(localizedPattern0, status);
171         failure(status, "df->toLocalizedPattern");
172         symbols->setLocalPatternChars(UnicodeString("abcdefghijklmonpqr")); // change value of field
173         UnicodeString format1;
174         format1 = df->format(d, format1);
175         if (format0 != format1) {
176             errln(UnicodeString("Formats are different. format0: ") + format0
177                 + UnicodeString("; format1: ") + format1);
178         }
179         UnicodeString localizedPattern1;
180         localizedPattern1 = df->toLocalizedPattern(localizedPattern1, status);
181         failure(status, "df->toLocalizedPattern");
182         if (localizedPattern0 != localizedPattern1) {
183             errln(UnicodeString("Pattern has been changed. localizedPattern0: ") + localizedPattern0
184                 + UnicodeString("; localizedPattern1: ") + localizedPattern1);
185         }
186         delete symbols;
187         delete df;
188     }
189     /*
190      * Test void SimpleDateFormat::setDateFormatSymbols (  const DateFormatSymbols & newFormatSymbols )
191      * Modifying the original DateFormatSymbols should not change the SimpleDateFormat's behavior.
192      */
193     {
194         UErrorCode status = U_ZERO_ERROR;
195         DateFormatSymbols* symbols = new DateFormatSymbols(Locale::getUS(), status);
196         if(failure(status, "new DateFormatSymbols")) return;
197         SimpleDateFormat *df = new SimpleDateFormat(UnicodeString("E hh:mm"), status);
198         if(failure(status, "new SimpleDateFormat")) return;
199         df->setDateFormatSymbols(*symbols);
200         UnicodeString format0;
201         format0 = df->format(d, format0);
202         UnicodeString localizedPattern0;
203         localizedPattern0 = df->toLocalizedPattern(localizedPattern0, status);
204         failure(status, "df->toLocalizedPattern");
205         symbols->setLocalPatternChars(UnicodeString("abcdefghijklmonpqr")); // change value of field
206         UnicodeString format1;
207         format1 = df->format(d, format1);
208         if (format0 != format1) {
209             errln(UnicodeString("Formats are different. format0: ") + format0
210                 + UnicodeString("; format1: ") + format1);
211         }
212         UnicodeString localizedPattern1;
213         localizedPattern1 = df->toLocalizedPattern(localizedPattern1, status);
214         failure(status, "df->toLocalizedPattern");
215         if (localizedPattern0 != localizedPattern1) {
216             errln(UnicodeString("Pattern has been changed. localizedPattern0: ") + localizedPattern0
217                 + UnicodeString("; localizedPattern1: ") + localizedPattern1);
218         }
219         delete symbols;
220         delete df;
221 
222     }
223     //Test the pointer version of the constructor (and the adoptDateFormatSymbols method)
224     {
225         UErrorCode status = U_ZERO_ERROR;
226         DateFormatSymbols* symbols = new DateFormatSymbols(Locale::getUS(), status);
227         if(failure(status, "new DateFormatSymbols")) return;
228         SimpleDateFormat *df = new SimpleDateFormat(UnicodeString("E hh:mm"), symbols, status);
229         if(failure(status, "new SimpleDateFormat")) return;
230         UnicodeString format0;
231         format0 = df->format(d, format0);
232         UnicodeString localizedPattern0;
233         localizedPattern0 = df->toLocalizedPattern(localizedPattern0, status);
234         failure(status, "df->toLocalizedPattern");
235         symbols->setLocalPatternChars(UnicodeString("abcdefghijklmonpqr")); // change value of field
236         UnicodeString format1;
237         format1 = df->format(d, format1);
238         if (format0 != format1) {
239             errln(UnicodeString("Formats are different. format0: ") + format0
240                 + UnicodeString("; format1: ") + format1);
241         }
242         UnicodeString localizedPattern1;
243         localizedPattern1 = df->toLocalizedPattern(localizedPattern1, status);
244         failure(status, "df->toLocalizedPattern");
245         if (localizedPattern0 == localizedPattern1) {
246             errln(UnicodeString("Pattern should have been changed. localizedPattern0: ") + localizedPattern0
247                 + UnicodeString("; localizedPattern1: ") + localizedPattern1);
248         }
249         //delete symbols; the caller is no longer responsible for deleting the symbols
250         delete df;
251     }
252     //
253     {
254         UErrorCode status = U_ZERO_ERROR;
255         DateFormatSymbols* symbols = new DateFormatSymbols(Locale::getUS(), status);
256         failure(status, "new DateFormatSymbols");
257         SimpleDateFormat *df = new SimpleDateFormat(UnicodeString("E hh:mm"), status);
258         if(failure(status, "new SimpleDateFormat")) return;
259         df-> adoptDateFormatSymbols(symbols);
260         UnicodeString format0;
261         format0 = df->format(d, format0);
262         UnicodeString localizedPattern0;
263         localizedPattern0 = df->toLocalizedPattern(localizedPattern0, status);
264         failure(status, "df->toLocalizedPattern");
265         symbols->setLocalPatternChars(UnicodeString("abcdefghijklmonpqr")); // change value of field
266         UnicodeString format1;
267         format1 = df->format(d, format1);
268         if (format0 != format1) {
269             errln(UnicodeString("Formats are different. format0: ") + format0
270                 + UnicodeString("; format1: ") + format1);
271         }
272         UnicodeString localizedPattern1;
273         localizedPattern1 = df->toLocalizedPattern(localizedPattern1, status);
274         failure(status, "df->toLocalizedPattern");
275         if (localizedPattern0 == localizedPattern1) {
276             errln(UnicodeString("Pattern should have been changed. localizedPattern0: ") + localizedPattern0
277                 + UnicodeString("; localizedPattern1: ") + localizedPattern1);
278         }
279         //delete symbols; the caller is no longer responsible for deleting the symbols
280         delete df;
281     }
282 }
283 
284 /*
285  * @test @(#)bug4117335.java    1.1 3/5/98
286  *
287  * @bug 4117335
288  */
289 void
test4117335()290 DateFormatMiscTests::test4117335()
291 {
292     //UnicodeString bc = "\u7d00\u5143\u524d";
293     UChar bcC [] = {
294         0x7D00,
295         0x5143,
296         0x524D
297     };
298     UnicodeString bc(bcC, 3, 3);
299 
300     //UnicodeString ad = "\u897f\u66a6";
301     UChar adC [] = {
302         0x897F,
303         0x66A6
304     };
305     UnicodeString ad(adC, 2, 2);
306 
307     //UnicodeString jstLong = "\u65e5\u672c\u6a19\u6e96\u6642";
308     UChar jstLongC [] = {
309         0x65e5,
310         0x672c,
311         0x6a19,
312         0x6e96,
313         0x6642
314     };
315     UChar jdtLongC [] = {0x65E5, 0x672C, 0x590F, 0x6642, 0x9593};
316 
317     UnicodeString jstLong(jstLongC, 5, 5);
318 
319 //    UnicodeString jstShort = "JST";
320 
321     UnicodeString tzID = "Asia/Tokyo";
322 
323     UnicodeString jdtLong(jdtLongC, 5, 5);
324 
325 //    UnicodeString jdtShort = "JDT";
326     UErrorCode status = U_ZERO_ERROR;
327     DateFormatSymbols *symbols = new DateFormatSymbols(Locale::getJapan(), status);
328     if(U_FAILURE(status)) {
329       dataerrln("Failure creating DateFormatSymbols, %s", u_errorName(status));
330       delete symbols;
331       return;
332     }
333     failure(status, "new DateFormatSymbols");
334     int32_t eraCount = 0;
335     const UnicodeString *eras = symbols->getEraNames(eraCount);
336 
337     logln(UnicodeString("BC = ") + eras[0]);
338     if (eras[0] != bc) {
339         errln("*** Should have been " + bc);
340         //throw new Exception("Error in BC");
341     }
342 
343     logln(UnicodeString("AD = ") + eras[1]);
344     if (eras[1] != ad) {
345         errln("*** Should have been " + ad);
346         //throw new Exception("Error in AD");
347     }
348 
349     int32_t rowCount, colCount;
350     const UnicodeString **zones = symbols->getZoneStrings(rowCount, colCount);
351     //don't hard code the index .. compute it.
352     int32_t index = -1;
353     for (int32_t i = 0; i < rowCount; ++i) {
354         if (tzID == (zones[i][0])) {
355             index = i;
356             break;
357         }
358     }
359     logln(UnicodeString("Long zone name = ") + zones[index][1]);
360     if (zones[index][1] != jstLong) {
361         errln("*** Should have been " + prettify(jstLong)+ " but it is: " + prettify(zones[index][1]));
362         //throw new Exception("Error in long TZ name");
363     }
364 //    logln(UnicodeString("Short zone name = ") + zones[index][2]);
365 //    if (zones[index][2] != jstShort) {
366 //        errln("*** Should have been " + prettify(jstShort) + " but it is: " + prettify(zones[index][2]));
367 //        //throw new Exception("Error in short TZ name");
368 //    }
369     logln(UnicodeString("Long zone name = ") + zones[index][3]);
370     if (zones[index][3] != jdtLong) {
371         errln("*** Should have been " + prettify(jstLong) + " but it is: " + prettify(zones[index][3]));
372         //throw new Exception("Error in long TZ name");
373     }
374 //    logln(UnicodeString("SHORT zone name = ") + zones[index][4]);
375 //    if (zones[index][4] != jdtShort) {
376 //        errln("*** Should have been " + prettify(jstShort)+ " but it is: " + prettify(zones[index][4]));
377 //        //throw new Exception("Error in short TZ name");
378 //    }
379     delete symbols;
380 
381 }
382 
383 #endif /* #if !UCONFIG_NO_FORMATTING */
384