1 /* 2 ********************************************************************** 3 * Copyright (c) 2010,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 defined(U_WINDOWS) 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 56 DateTimeRoundTripFunction() 57 { 58 nLocales = 0; 59 } 60 61 DateTimeRoundTripFunction(int locs) 62 { 63 nLocales = locs; 64 } 65 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 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