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