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 UChar* lpSrcStr,int cchSrc, UChar* 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 virtual void call(UErrorCode* status) 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 UDate low, high; 94 cal->set(1900, UCAL_JANUARY, 1); 95 low = cal->getTime(*status); 96 cal->set(2040, UCAL_JANUARY, 1); 97 high = cal->getTime(*status); 98 if (U_FAILURE(*status)) { 99 //errln("getTime failed"); 100 return; 101 } 102 103 // Set up test dates 104 UDate DATES[UPRV_LENGTHOF(testDateData)/3]; 105 const int32_t nDates = UPRV_LENGTHOF(testDateData)/3; 106 cal->clear(); 107 for (int32_t i = 0; i < nDates; i++) { 108 cal->set(testDateData[i][0], testDateData[i][1], testDateData[i][2]); 109 DATES[i] = cal->getTime(*status); 110 if (U_FAILURE(*status)) { 111 //errln("getTime failed"); 112 return; 113 } 114 } 115 116 // Set up test locales 117 const Locale testLocales[] = { 118 Locale("en"), 119 Locale("en_US"), 120 Locale("en_AU"), 121 Locale("de_DE"), 122 Locale("fr"), 123 Locale("ja_JP"), 124 Locale("ko"), 125 Locale("pt"), 126 Locale("th_TH"), 127 Locale("zh_Hans"), 128 129 Locale("it"), 130 131 Locale("en"), 132 Locale("en_US"), 133 Locale("en_AU"), 134 Locale("de_DE"), 135 Locale("fr"), 136 Locale("ja_JP"), 137 Locale("ko"), 138 Locale("pt"), 139 Locale("th_TH"), 140 Locale("zh_Hans"), 141 }; 142 143 const Locale *LOCALES; 144 LOCALES = testLocales; 145 146 StringEnumeration *tzids = TimeZone::createEnumeration(*status); 147 if (U_FAILURE(*status)) { 148 //errln("tzids->count failed"); 149 return; 150 } 151 152 // Run the roundtrip test 153 for (int32_t locidx = 0; locidx < nLocales; locidx++) { 154 for (int32_t patidx = 0; patidx < NUM_PATTERNS; patidx++) { 155 SimpleDateFormat *sdf = new SimpleDateFormat((UnicodeString)PATTERNS[patidx], LOCALES[locidx], *status); 156 if (U_FAILURE(*status)) { 157 //errcheckln(*status, (UnicodeString)"new SimpleDateFormat failed for pattern " + 158 // PATTERNS[patidx] + " for locale " + LOCALES[locidx].getName() + " - " + u_errorName(*status)); 159 *status = U_ZERO_ERROR; 160 continue; 161 } 162 163 tzids->reset(*status); 164 const UnicodeString *tzid; 165 while ((tzid = tzids->snext(*status))) { 166 TimeZone *tz = TimeZone::createTimeZone(*tzid); 167 168 for (int32_t datidx = 0; datidx < nDates; datidx++) { 169 UnicodeString tzstr; 170 FieldPosition fpos(FieldPosition::DONT_CARE); 171 172 // Format 173 sdf->setTimeZone(*tz); 174 sdf->format(DATES[datidx], tzstr, fpos); 175 176 // Before parse, set unknown zone to SimpleDateFormat instance 177 // just for making sure that it does not depends on the time zone 178 // originally set. 179 sdf->setTimeZone(unknownZone); 180 181 // Parse 182 ParsePosition pos(0); 183 Calendar *outcal = Calendar::createInstance(unknownZone, *status); 184 if (U_FAILURE(*status)) { 185 //errln("Failed to create an instance of calendar for receiving parse result."); 186 *status = U_ZERO_ERROR; 187 continue; 188 } 189 outcal->set(UCAL_DST_OFFSET, badDstOffset); 190 outcal->set(UCAL_ZONE_OFFSET, badZoneOffset); 191 sdf->parse(tzstr, *outcal, pos); 192 193 // clean loop 194 delete outcal; 195 196 } 197 delete tz; 198 // break time zone loop 199 break; 200 201 } 202 delete sdf; 203 } 204 } 205 delete cal; 206 delete tzids; 207 208 } 209 getOperationsPerIteration()210 virtual long getOperationsPerIteration() 211 { 212 return NUM_PATTERNS * nLocales * 6; 213 } 214 }; 215 216 217 class DateTimeRoundTripPerfTest : public UPerfTest 218 { 219 private: 220 221 public: 222 223 DateTimeRoundTripPerfTest(int32_t argc, const char* argv[], UErrorCode& status); 224 ~DateTimeRoundTripPerfTest(); 225 virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec,const char* &name, char* par); 226 227 UPerfFunction* RoundTripLocale1(); 228 UPerfFunction* RoundTripLocale10(); 229 UPerfFunction* RoundTripLocale11(); 230 UPerfFunction* RoundTripLocale21(); 231 }; 232 233 234 #endif // DateTimeRoundTripPerfTest 235