• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 **********************************************************************
5 * Copyright (c) 2010-2016,International Business Machines
6 * Corporation and others.  All Rights Reserved.
7 **********************************************************************
8 **********************************************************************
9 */
10 
11 #ifndef _DTFMTRTPERF_H
12 #define _DTFMTRTPERF_H
13 
14 #include "unicode/utypes.h"
15 #include "unicode/uperf.h"
16 #include "unicode/timezone.h"
17 #include "unicode/simpletz.h"
18 #include "unicode/calendar.h"
19 #include "unicode/strenum.h"
20 #include "unicode/smpdtfmt.h"
21 #include "unicode/uchar.h"
22 #include "unicode/basictz.h"
23 #include "cmemory.h"
24 #include "cstring.h"
25 
26 #include "unicode/uperf.h"
27 #include "unicode/unistr.h"
28 #include "unicode/datefmt.h"
29 #include "unicode/calendar.h"
30 #include "unicode/uclean.h"
31 #include "unicode/brkiter.h"
32 #include "util.h"
33 
34 static const char* PATTERNS[] = {"z", "zzzz", "Z", "ZZZZ", "v", "vvvv", "V", "VVVV"};
35 static const int NUM_PATTERNS = UPRV_LENGTHOF(PATTERNS);
36 
37 #include <iostream>
38 #include <stdlib.h>
39 #include <fstream>
40 #include <string>
41 using namespace std;
42 
43 //  Stubs for Windows API functions when building on UNIXes.
44 //
45 #if U_PLATFORM_USES_ONLY_WIN32_API
46 // do nothing
47 #else
48 #define _UNICODE
49 typedef int DWORD;
50 inline int FoldStringW(DWORD dwMapFlags, const char16_t* lpSrcStr,int cchSrc, char16_t* lpDestStr,int cchDest);
51 #endif
52 
53 class DateTimeRoundTripFunction : public UPerfFunction
54 {
55 private:
56 	int nLocales;
57 public:
58 
DateTimeRoundTripFunction()59 	DateTimeRoundTripFunction()
60 	{
61 		nLocales = 0;
62 	}
63 
DateTimeRoundTripFunction(int locs)64 	DateTimeRoundTripFunction(int locs)
65 	{
66 		nLocales = locs;
67 	}
68 
call(UErrorCode * status)69 	void call(UErrorCode* status) override
70 	{
71         *status = U_ZERO_ERROR;
72 
73         SimpleTimeZone unknownZone(-31415, UnicodeString("Etc/Unknown"));
74         int32_t badDstOffset = -1234;
75         int32_t badZoneOffset = -2345;
76 
77         int32_t testDateData[][3] = {
78             {2007, 1, 15},
79             {2007, 6, 15},
80             {1990, 1, 15},
81             {1990, 6, 15},
82             {1960, 1, 15},
83             {1960, 6, 15},
84         };
85 
86         Calendar *cal = Calendar::createInstance(*status);
87         if (U_FAILURE(*status)) {
88             //dataerrln("Calendar::createInstance failed: %s", u_errorName(*status));
89             return;
90         }
91 
92         // Set up rule equivalency test range
93         cal->set(1900, UCAL_JANUARY, 1);
94         cal->getTime(*status);
95         cal->set(2040, UCAL_JANUARY, 1);
96         cal->getTime(*status);
97         if (U_FAILURE(*status)) {
98             //errln("getTime failed");
99             return;
100         }
101 
102         // Set up test dates
103         UDate DATES[UPRV_LENGTHOF(testDateData)/3];
104         const int32_t nDates = UPRV_LENGTHOF(testDateData)/3;
105         cal->clear();
106         for (int32_t i = 0; i < nDates; i++) {
107             cal->set(testDateData[i][0], testDateData[i][1], testDateData[i][2]);
108             DATES[i] = cal->getTime(*status);
109             if (U_FAILURE(*status)) {
110                 //errln("getTime failed");
111                 return;
112             }
113         }
114 
115         // Set up test locales
116         const Locale testLocales[] = {
117             Locale("en"),
118             Locale("en_US"),
119             Locale("en_AU"),
120             Locale("de_DE"),
121             Locale("fr"),
122             Locale("ja_JP"),
123             Locale("ko"),
124             Locale("pt"),
125             Locale("th_TH"),
126             Locale("zh_Hans"),
127 
128             Locale("it"),
129 
130             Locale("en"),
131             Locale("en_US"),
132             Locale("en_AU"),
133             Locale("de_DE"),
134             Locale("fr"),
135             Locale("ja_JP"),
136             Locale("ko"),
137             Locale("pt"),
138             Locale("th_TH"),
139             Locale("zh_Hans"),
140         };
141 
142         const Locale *LOCALES;
143         LOCALES = testLocales;
144 
145         StringEnumeration *tzids = TimeZone::createEnumeration(*status);
146         if (U_FAILURE(*status)) {
147             //errln("tzids->count failed");
148             return;
149         }
150 
151         // Run the roundtrip test
152         for (int32_t locidx = 0; locidx < nLocales; locidx++) {
153             for (int32_t patidx = 0; patidx < NUM_PATTERNS; patidx++) {
154                 SimpleDateFormat* sdf = new SimpleDateFormat(UnicodeString(PATTERNS[patidx]), LOCALES[locidx], *status);
155                 if (U_FAILURE(*status)) {
156                     //errcheckln(*status, (UnicodeString)"new SimpleDateFormat failed for pattern " +
157                     //    PATTERNS[patidx] + " for locale " + LOCALES[locidx].getName() + " - " + u_errorName(*status));
158                     *status = U_ZERO_ERROR;
159                     continue;
160                 }
161 
162                 tzids->reset(*status);
163                 const UnicodeString *tzid;
164                 while ((tzid = tzids->snext(*status))) {
165                     TimeZone *tz = TimeZone::createTimeZone(*tzid);
166 
167                     for (int32_t datidx = 0; datidx < nDates; datidx++) {
168                         UnicodeString tzstr;
169                         FieldPosition fpos(FieldPosition::DONT_CARE);
170 
171                         // Format
172                         sdf->setTimeZone(*tz);
173                         sdf->format(DATES[datidx], tzstr, fpos);
174 
175                         // Before parse, set unknown zone to SimpleDateFormat instance
176                         // just for making sure that it does not depends on the time zone
177                         // originally set.
178                         sdf->setTimeZone(unknownZone);
179 
180                         // Parse
181                         ParsePosition pos(0);
182                         Calendar *outcal = Calendar::createInstance(unknownZone, *status);
183                         if (U_FAILURE(*status)) {
184                             //errln("Failed to create an instance of calendar for receiving parse result.");
185                             *status = U_ZERO_ERROR;
186                             continue;
187                         }
188                         outcal->set(UCAL_DST_OFFSET, badDstOffset);
189                         outcal->set(UCAL_ZONE_OFFSET, badZoneOffset);
190                         sdf->parse(tzstr, *outcal, pos);
191 
192                         // clean loop
193                         delete outcal;
194 
195                     }
196                     delete tz;
197                     // break  time zone loop
198                     break;
199 
200                 }
201                 delete sdf;
202             }
203         }
204         delete cal;
205         delete tzids;
206 
207 	}
208 
getOperationsPerIteration()209 	long getOperationsPerIteration() override
210 	{
211 		return NUM_PATTERNS * nLocales * 6;
212 	}
213 };
214 
215 
216 class DateTimeRoundTripPerfTest : public UPerfTest
217 {
218 private:
219 
220 public:
221 
222 	DateTimeRoundTripPerfTest(int32_t argc, const char* argv[], UErrorCode& status);
223 	~DateTimeRoundTripPerfTest();
224 	UPerfFunction* runIndexedTest(int32_t index, UBool exec, const char*& name, char* par) override;
225 
226 	UPerfFunction* RoundTripLocale1();
227 	UPerfFunction* RoundTripLocale10();
228 	UPerfFunction* RoundTripLocale11();
229 	UPerfFunction* RoundTripLocale21();
230 };
231 
232 
233 #endif // DateTimeRoundTripPerfTest
234