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