// © 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 <iostream>
#include <stdlib.h>
#include <fstream>
#include <string>
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