// © 2016 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** * Copyright (c) 2010-2016,International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** ********************************************************************** */ #ifndef _DTFMTRTPERF_H #define _DTFMTRTPERF_H #include "unicode/utypes.h" #include "unicode/uperf.h" #include "unicode/timezone.h" #include "unicode/simpletz.h" #include "unicode/calendar.h" #include "unicode/strenum.h" #include "unicode/smpdtfmt.h" #include "unicode/uchar.h" #include "unicode/basictz.h" #include "cmemory.h" #include "cstring.h" #include "unicode/uperf.h" #include "unicode/unistr.h" #include "unicode/datefmt.h" #include "unicode/calendar.h" #include "unicode/uclean.h" #include "unicode/brkiter.h" #include "util.h" static const char* PATTERNS[] = {"z", "zzzz", "Z", "ZZZZ", "v", "vvvv", "V", "VVVV"}; static const int NUM_PATTERNS = UPRV_LENGTHOF(PATTERNS); #include #include #include #include using namespace std; // Stubs for Windows API functions when building on UNIXes. // #if U_PLATFORM_USES_ONLY_WIN32_API // do nothing #else #define _UNICODE typedef int DWORD; inline int FoldStringW(DWORD dwMapFlags, const UChar* lpSrcStr,int cchSrc, UChar* lpDestStr,int cchDest); #endif class DateTimeRoundTripFunction : public UPerfFunction { private: int nLocales; public: DateTimeRoundTripFunction() { nLocales = 0; } DateTimeRoundTripFunction(int locs) { nLocales = locs; } virtual void call(UErrorCode* status) { *status = U_ZERO_ERROR; SimpleTimeZone unknownZone(-31415, (UnicodeString)"Etc/Unknown"); int32_t badDstOffset = -1234; int32_t badZoneOffset = -2345; int32_t testDateData[][3] = { {2007, 1, 15}, {2007, 6, 15}, {1990, 1, 15}, {1990, 6, 15}, {1960, 1, 15}, {1960, 6, 15}, }; Calendar *cal = Calendar::createInstance(*status); if (U_FAILURE(*status)) { //dataerrln("Calendar::createInstance failed: %s", u_errorName(*status)); return; } // Set up rule equivalency test range UDate low, high; cal->set(1900, UCAL_JANUARY, 1); low = cal->getTime(*status); cal->set(2040, UCAL_JANUARY, 1); high = cal->getTime(*status); if (U_FAILURE(*status)) { //errln("getTime failed"); return; } // Set up test dates UDate DATES[UPRV_LENGTHOF(testDateData)/3]; const int32_t nDates = UPRV_LENGTHOF(testDateData)/3; cal->clear(); for (int32_t i = 0; i < nDates; i++) { cal->set(testDateData[i][0], testDateData[i][1], testDateData[i][2]); DATES[i] = cal->getTime(*status); if (U_FAILURE(*status)) { //errln("getTime failed"); return; } } // Set up test locales const Locale testLocales[] = { Locale("en"), Locale("en_US"), Locale("en_AU"), Locale("de_DE"), Locale("fr"), Locale("ja_JP"), Locale("ko"), Locale("pt"), Locale("th_TH"), Locale("zh_Hans"), Locale("it"), Locale("en"), Locale("en_US"), Locale("en_AU"), Locale("de_DE"), Locale("fr"), Locale("ja_JP"), Locale("ko"), Locale("pt"), Locale("th_TH"), Locale("zh_Hans"), }; const Locale *LOCALES; LOCALES = testLocales; StringEnumeration *tzids = TimeZone::createEnumeration(); if (U_FAILURE(*status)) { //errln("tzids->count failed"); return; } // Run the roundtrip test for (int32_t locidx = 0; locidx < nLocales; locidx++) { for (int32_t patidx = 0; patidx < NUM_PATTERNS; patidx++) { SimpleDateFormat *sdf = new SimpleDateFormat((UnicodeString)PATTERNS[patidx], LOCALES[locidx], *status); if (U_FAILURE(*status)) { //errcheckln(*status, (UnicodeString)"new SimpleDateFormat failed for pattern " + // PATTERNS[patidx] + " for locale " + LOCALES[locidx].getName() + " - " + u_errorName(*status)); *status = U_ZERO_ERROR; continue; } tzids->reset(*status); const UnicodeString *tzid; while ((tzid = tzids->snext(*status))) { TimeZone *tz = TimeZone::createTimeZone(*tzid); for (int32_t datidx = 0; datidx < nDates; datidx++) { UnicodeString tzstr; FieldPosition fpos(FieldPosition::DONT_CARE); // Format sdf->setTimeZone(*tz); sdf->format(DATES[datidx], tzstr, fpos); // Before parse, set unknown zone to SimpleDateFormat instance // just for making sure that it does not depends on the time zone // originally set. sdf->setTimeZone(unknownZone); // Parse ParsePosition pos(0); Calendar *outcal = Calendar::createInstance(unknownZone, *status); if (U_FAILURE(*status)) { //errln("Failed to create an instance of calendar for receiving parse result."); *status = U_ZERO_ERROR; continue; } outcal->set(UCAL_DST_OFFSET, badDstOffset); outcal->set(UCAL_ZONE_OFFSET, badZoneOffset); sdf->parse(tzstr, *outcal, pos); // clean loop delete outcal; } delete tz; // break time zone loop break; } delete sdf; } } delete cal; delete tzids; } virtual long getOperationsPerIteration() { return NUM_PATTERNS * nLocales * 6; } }; class DateTimeRoundTripPerfTest : public UPerfTest { private: public: DateTimeRoundTripPerfTest(int32_t argc, const char* argv[], UErrorCode& status); ~DateTimeRoundTripPerfTest(); virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec,const char* &name, char* par); UPerfFunction* RoundTripLocale1(); UPerfFunction* RoundTripLocale10(); UPerfFunction* RoundTripLocale11(); UPerfFunction* RoundTripLocale21(); }; #endif // DateTimeRoundTripPerfTest