ICU-21372 getOffsetFromLocal for C and C++

See #1610
This commit is contained in:
yumaoka 2021-03-02 02:21:48 +00:00 committed by Yoshito Umaoka
parent c231cf7c4f
commit 53aa0505c5
14 changed files with 431 additions and 44 deletions

View file

@ -547,14 +547,23 @@ error:
}
void
BasicTimeZone::getOffsetFromLocal(UDate /*date*/, int32_t /*nonExistingTimeOpt*/, int32_t /*duplicatedTimeOpt*/,
int32_t& /*rawOffset*/, int32_t& /*dstOffset*/, UErrorCode& status) const {
BasicTimeZone::getOffsetFromLocal(UDate /*date*/, UTimeZoneLocalOption /*nonExistingTimeOpt*/,
UTimeZoneLocalOption /*duplicatedTimeOpt*/,
int32_t& /*rawOffset*/, int32_t& /*dstOffset*/,
UErrorCode& status) const {
if (U_FAILURE(status)) {
return;
}
status = U_UNSUPPORTED_ERROR;
}
void BasicTimeZone::getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
int32_t& rawOffset, int32_t& dstOffset,
UErrorCode& status) const {
getOffsetFromLocal(date, (UTimeZoneLocalOption)nonExistingTimeOpt,
(UTimeZoneLocalOption)duplicatedTimeOpt, rawOffset, dstOffset, status);
}
U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */

View file

@ -399,9 +399,9 @@ void OlsonTimeZone::getOffset(UDate date, UBool local, int32_t& rawoff,
}
}
void
OlsonTimeZone::getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
int32_t& rawoff, int32_t& dstoff, UErrorCode& ec) const {
void OlsonTimeZone::getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt,
int32_t& rawoff, int32_t& dstoff, UErrorCode& ec) const {
if (U_FAILURE(ec)) {
return;
}

View file

@ -187,8 +187,10 @@ class U_I18N_API OlsonTimeZone: public BasicTimeZone {
/**
* BasicTimeZone API.
*/
virtual void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
int32_t& rawoff, int32_t& dstoff, UErrorCode& ec) const;
virtual void getOffsetFromLocal(
UDate date, UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt,
int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const;
/**
* TimeZone API. This method has no effect since objects of this

View file

@ -403,9 +403,9 @@ RuleBasedTimeZone::getOffset(UDate date, UBool local, int32_t& rawOffset,
getOffsetInternal(date, local, kFormer, kLatter, rawOffset, dstOffset, status);
}
void
RuleBasedTimeZone::getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const {
void RuleBasedTimeZone::getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt,
int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const {
getOffsetInternal(date, TRUE, nonExistingTimeOpt, duplicatedTimeOpt, rawOffset, dstOffset, status);
}

View file

@ -509,8 +509,10 @@ SimpleTimeZone::getOffset(uint8_t era, int32_t year, int32_t month, int32_t day,
}
void
SimpleTimeZone::getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
int32_t& rawOffsetGMT, int32_t& savingsDST, UErrorCode& status) const {
SimpleTimeZone::getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt, int32_t& rawOffsetGMT,
int32_t& savingsDST, UErrorCode& status) const
{
if (U_FAILURE(status)) {
return;
}

View file

@ -828,4 +828,28 @@ ucal_getTimeZoneIDForWindowsID(const UChar* winid, int32_t len, const char* regi
return resultLen;
}
U_CAPI void U_EXPORT2 ucal_getTimeZoneOffsetFromLocal(
const UCalendar* cal,
UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt,
int32_t* rawOffset, int32_t* dstOffset, UErrorCode* status)
{
if (U_FAILURE(*status)) {
return;
}
UDate date = ((Calendar*)cal)->getTime(*status);
if (U_FAILURE(*status)) {
return;
}
const TimeZone& tz = ((Calendar*)cal)->getTimeZone();
const BasicTimeZone* btz = dynamic_cast<const BasicTimeZone *>(&tz);
if (btz == nullptr) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
btz->getOffsetFromLocal(
date, nonExistingTimeOpt, duplicatedTimeOpt,
*rawOffset, *dstOffset, *status);
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View file

@ -152,6 +152,17 @@ public:
virtual void getSimpleRulesNear(UDate date, InitialTimeZoneRule*& initial,
AnnualTimeZoneRule*& std, AnnualTimeZoneRule*& dst, UErrorCode& status) const;
#ifndef U_FORCE_HIDE_DRAFT_API
/**
* Get time zone offsets from local wall time.
* @draft ICU 69
*/
virtual void getOffsetFromLocal(
UDate date, UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt, int32_t& rawOffset,
int32_t& dstOffset, UErrorCode& status) const;
#endif /* U_FORCE_HIDE_DRAFT_API */
#ifndef U_HIDE_INTERNAL_API
/**
@ -161,8 +172,8 @@ public:
enum {
kStandard = 0x01,
kDaylight = 0x03,
kFormer = 0x04,
kLatter = 0x0C
kFormer = 0x04, /* UCAL_TZ_LOCAL_FORMER */
kLatter = 0x0C /* UCAL_TZ_LOCAL_LATTER */
};
#endif /* U_HIDE_INTERNAL_API */
@ -170,7 +181,7 @@ public:
* Get time zone offsets from local wall time.
* @internal
*/
virtual void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const;
protected:

View file

@ -302,12 +302,16 @@ public:
virtual void getTimeZoneRules(const InitialTimeZoneRule*& initial,
const TimeZoneRule* trsrules[], int32_t& trscount, UErrorCode& status) const;
#ifndef U_FORCE_HIDE_DRAFT_API
/**
* Get time zone offsets from local wall time.
* @internal
* @draft ICU 69
*/
virtual void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
virtual void getOffsetFromLocal(
UDate date, UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt,
int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const;
#endif /* U_FORCE_HIDE_DRAFT_API */
private:
void deleteRules(void);

View file

@ -620,12 +620,16 @@ public:
virtual void getOffset(UDate date, UBool local, int32_t& rawOffset,
int32_t& dstOffset, UErrorCode& ec) const;
#ifndef U_FORCE_HIDE_DRAFT_API
/**
* Get time zone offsets from local wall time.
* @internal
* @draft ICU 69
*/
virtual void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
virtual void getOffsetFromLocal(
UDate date, UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt,
int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const;
#endif /* U_FORCE_HIDE_DRAFT_API */
/**
* Returns the TimeZone's raw GMT offset (i.e., the number of milliseconds to add

View file

@ -1617,6 +1617,102 @@ U_CAPI int32_t U_EXPORT2
ucal_getTimeZoneIDForWindowsID(const UChar* winid, int32_t len, const char* region,
UChar* id, int32_t idCapacity, UErrorCode* status);
#ifndef U_FORCE_HIDE_DRAFT_API
/**
* Options used by ucal_getTimeZoneOffsetFromLocal and BasicTimeZone::getOffsetFromLocal()
* to specify how to interpret an input time when it does not exist, or when it is ambiguous,
* around a time zone transition.
* @draft ICU 69
*/
enum UTimeZoneLocalOption {
#ifndef U_HIDE_DRAFT_API
/**
* An input time is always interpreted as local time before
* a time zone transition.
* @draft ICU 69
*/
UCAL_TZ_LOCAL_FORMER = 0x04,
/**
* An input time is always interpreted as local time after
* a time zone transition.
* @draft ICU 69
*/
UCAL_TZ_LOCAL_LATTER = 0x0C,
/**
* An input time is interpreted as standard time when local
* time is switched to/from daylight saving time. When both
* sides of a time zone transition are standard time,
* or daylight saving time, the local time before the
* transition is used.
* @draft ICU 69
*/
UCAL_TZ_LOCAL_STANDARD_FORMER = UCAL_TZ_LOCAL_FORMER | 0x01,
/**
* An input time is interpreted as standard time when local
* time is switched to/from daylight saving time. When both
* sides of a time zone transition are standard time,
* or daylight saving time, the local time after the
* transition is used.
* @draft ICU 69
*/
UCAL_TZ_LOCAL_STANDARD_LATTER = UCAL_TZ_LOCAL_LATTER | 0x01,
/**
* An input time is interpreted as daylight saving time when
* local time is switched to/from standard time. When both
* sides of a time zone transition are standard time,
* or daylight saving time, the local time before the
* transition is used.
* @draft ICU 69
*/
UCAL_TZ_LOCAL_DAYLIGHT_FORMER = UCAL_TZ_LOCAL_FORMER | 0x03,
/**
* An input time is interpreted as daylight saving time when
* local time is switched to/from standard time. When both
* sides of a time zone transition are standard time,
* or daylight saving time, the local time after the
* transition is used.
* @draft ICU 69
*/
UCAL_TZ_LOCAL_DAYLIGHT_LATTER = UCAL_TZ_LOCAL_LATTER | 0x03,
#endif /* U_HIDE_DRAFT_API */
};
typedef enum UTimeZoneLocalOption UTimeZoneLocalOption; /**< @draft ICU 69 */
/**
* Returns the time zone raw and GMT offset for the given moment
* in time. Upon return, local-millis = GMT-millis + rawOffset +
* dstOffset. All computations are performed in the proleptic
* Gregorian calendar.
*
* @param cal The UCalendar which specify the local date and time value to query.
* @param nonExistingTimeOpt The option to indicate how to interpret the date and
* time in the calendar represent a local time that skipped at a positive time
* zone transitions (e.g. when the daylight saving time starts or the time zone
* offset is increased due to a time zone rule change).
* @param duplicatedTimeOpt The option to indicate how to interpret the date and
* time in the calendar represent a local time that repeating multiple times at a
* negative time zone transition (e.g. when the daylight saving time ends or the
* time zone offset is decreased due to a time zone rule change)
* @param rawOffset output parameter to receive the raw offset, that
* is, the offset not including DST adjustments.
* If the status is set to one of the error code, the value set is unspecified.
* @param dstOffset output parameter to receive the DST offset,
* that is, the offset to be added to `rawOffset' to obtain the
* total offset between local and GMT time. If DST is not in
* effect, this value is zero; otherwise it is a positive value,
* typically one hour.
* If the status is set to one of the error code, the value set is unspecified.
* @param status A pointer to a UErrorCode to receive any errors.
* @draft ICU 69
*/
U_CAPI void U_EXPORT2
ucal_getTimeZoneOffsetFromLocal(
const UCalendar* cal,
UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt,
int32_t* rawOffset, int32_t* dstOffset, UErrorCode* status);
#endif /* U_FORCE_HIDE_DRAFT_API */
#endif /* #if !UCONFIG_NO_FORMATTING */
#endif

View file

@ -264,6 +264,17 @@ public:
virtual void getOffset(UDate date, UBool local, int32_t& rawOffset,
int32_t& dstOffset, UErrorCode& ec) const;
#ifndef U_FORCE_HIDE_DRAFT_API
/**
* Get time zone offsets from local wall time.
* @draft ICU 69
*/
virtual void getOffsetFromLocal(
UDate date, UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt,
int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const;
#endif /* U_FORCE_HIDE_DRAFT_API */
/**
* Sets the TimeZone's raw GMT offset (i.e., the number of milliseconds to add
* to GMT to get local time, before taking daylight savings time into account).

View file

@ -1217,6 +1217,12 @@ VTimeZone::getOffset(UDate date, UBool local, int32_t& rawOffset,
return tz->getOffset(date, local, rawOffset, dstOffset, status);
}
void VTimeZone::getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt,
int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const {
tz->getOffsetFromLocal(date, nonExistingTimeOpt, duplicatedTimeOpt, rawOffset, dstOffset, status);
}
void
VTimeZone::setRawOffset(int32_t offsetMillis) {
tz->setRawOffset(offsetMillis);

View file

@ -41,6 +41,7 @@ void TestGetWindowsTimeZoneID(void);
void TestGetTimeZoneIDByWindowsID(void);
void TestJpnCalAddSetNextEra(void);
void TestUcalOpenBufferRead(void);
void TestGetTimeZoneOffsetFromLocal(void);
void addCalTest(TestNode** root);
@ -65,6 +66,7 @@ void addCalTest(TestNode** root)
addTest(root, &TestGetTimeZoneIDByWindowsID, "tsformat/ccaltst/TestGetTimeZoneIDByWindowsID");
addTest(root, &TestJpnCalAddSetNextEra, "tsformat/ccaltst/TestJpnCalAddSetNextEra");
addTest(root, &TestUcalOpenBufferRead, "tsformat/ccaltst/TestUcalOpenBufferRead");
addTest(root, &TestGetTimeZoneOffsetFromLocal, "tsformat/ccaltst/TestGetTimeZoneOffsetFromLocal");
}
/* "GMT" */
@ -2553,4 +2555,220 @@ void TestUcalOpenBufferRead() {
ucal_close(cal);
}
/*
* Testing ucal_getTimeZoneOffsetFromLocal
*/
void
TestGetTimeZoneOffsetFromLocal() {
static const UChar utc[] = u"Etc/GMT";
const int32_t HOUR = 60*60*1000;
const int32_t MINUTE = 60*1000;
const int32_t DATES[][6] = {
{2006, UCAL_APRIL, 2, 1, 30, 1*HOUR+30*MINUTE},
{2006, UCAL_APRIL, 2, 2, 00, 2*HOUR},
{2006, UCAL_APRIL, 2, 2, 30, 2*HOUR+30*MINUTE},
{2006, UCAL_APRIL, 2, 3, 00, 3*HOUR},
{2006, UCAL_APRIL, 2, 3, 30, 3*HOUR+30*MINUTE},
{2006, UCAL_OCTOBER, 29, 0, 30, 0*HOUR+30*MINUTE},
{2006, UCAL_OCTOBER, 29, 1, 00, 1*HOUR},
{2006, UCAL_OCTOBER, 29, 1, 30, 1*HOUR+30*MINUTE},
{2006, UCAL_OCTOBER, 29, 2, 00, 2*HOUR},
{2006, UCAL_OCTOBER, 29, 2, 30, 2*HOUR+30*MINUTE},
};
// Expected offsets by
// void U_ucal_getTimeZoneOffsetFromLocal(
// const UCalendar* cal,
// UTimeZoneLocalOption nonExistingTimeOpt,
// UTimeZoneLocalOption duplicatedTimeOpt,
// int32_t* rawOffset, int32_t* dstOffset, UErrorCode* status);
// with nonExistingTimeOpt=UCAL_TZ_LOCAL_STANDARD and
// duplicatedTimeOpt=UCAL_TZ_LOCAL_STANDARD
const int32_t OFFSETS2[][2] = {
// April 2, 2006
{-8*HOUR, 0},
{-8*HOUR, 0},
{-8*HOUR, 0},
{-8*HOUR, 1*HOUR},
{-8*HOUR, 1*HOUR},
// Oct 29, 2006
{-8*HOUR, 1*HOUR},
{-8*HOUR, 0},
{-8*HOUR, 0},
{-8*HOUR, 0},
{-8*HOUR, 0},
};
// Expected offsets by
// void U_ucal_getTimeZoneOffsetFromLocal(
// const UCalendar* cal,
// UTimeZoneLocalOption nonExistingTimeOpt,
// UTimeZoneLocalOption duplicatedTimeOpt,
// int32_t* rawOffset, int32_t* dstOffset, UErrorCode* status);
// with nonExistingTimeOpt=UCAL_TZ_LOCAL_DAYLIGHT and
// duplicatedTimeOpt=UCAL_TZ_LOCAL_DAYLIGHT
const int32_t OFFSETS3[][2] = {
// April 2, 2006
{-8*HOUR, 0},
{-8*HOUR, 1*HOUR},
{-8*HOUR, 1*HOUR},
{-8*HOUR, 1*HOUR},
{-8*HOUR, 1*HOUR},
// October 29, 2006
{-8*HOUR, 1*HOUR},
{-8*HOUR, 1*HOUR},
{-8*HOUR, 1*HOUR},
{-8*HOUR, 0},
{-8*HOUR, 0},
};
UErrorCode status = U_ZERO_ERROR;
int32_t rawOffset, dstOffset;
UCalendar *cal = ucal_open(utc, -1, "en", UCAL_GREGORIAN, &status);
if (U_FAILURE(status)) {
log_data_err("ucal_open: %s", u_errorName(status));
return;
}
// Calculate millis
UDate MILLIS[UPRV_LENGTHOF(DATES)];
for (int32_t i = 0; i < UPRV_LENGTHOF(DATES); i++) {
ucal_setDateTime(cal, DATES[i][0], DATES[i][1], DATES[i][2],
DATES[i][3], DATES[i][4], 0, &status);
MILLIS[i] = ucal_getMillis(cal, &status);
if (U_FAILURE(status)) {
log_data_err("ucal_getMillis failed");
return;
}
}
ucal_setTimeZone(cal, AMERICA_LOS_ANGELES, -1, &status);
// Test void ucal_getTimeZoneOffsetFromLocal(
// const UCalendar* cal,
// UTimeZoneLocalOption nonExistingTimeOpt,
// UTimeZoneLocalOption duplicatedTimeOpt,
// int32_t* rawOffset, int32_t* dstOffset, UErrorCode* status);
// with nonExistingTimeOpt=UCAL_TZ_LOCAL_STANDARD and
// duplicatedTimeOpt=UCAL_TZ_LOCAL_STANDARD
for (int m = 0; m < UPRV_LENGTHOF(DATES); m++) {
status = U_ZERO_ERROR;
ucal_setMillis(cal, MILLIS[m], &status);
if (U_FAILURE(status)) {
log_data_err("ucal_setMillis: %s\n", u_errorName(status));
}
ucal_getTimeZoneOffsetFromLocal(cal, UCAL_TZ_LOCAL_STANDARD_FORMER, UCAL_TZ_LOCAL_STANDARD_LATTER,
&rawOffset, &dstOffset, &status);
if (U_FAILURE(status)) {
log_err("ERROR: ucal_getTimeZoneOffsetFromLocal((%d-%d-%d %d:%d:0),"
"UCAL_TZ_LOCAL_STANDARD_FORMER, UCAL_TZ_LOCAL_STANDARD_LATTER: %s\n",
DATES[m][0], DATES[m][1], DATES[m][2], DATES[m][3], DATES[m][4],
u_errorName(status));
} else if (rawOffset != OFFSETS2[m][0] || dstOffset != OFFSETS2[m][1]) {
log_err("Bad offset returned at (%d-%d-%d %d:%d:0) "
"(wall/UCAL_TZ_LOCAL_STANDARD_FORMER/UCAL_TZ_LOCAL_STANDARD_LATTER) \n- Got: %d / %d "
" Expected %d / %d\n",
DATES[m][0], DATES[m][1], DATES[m][2], DATES[m][3], DATES[m][4],
rawOffset, dstOffset, OFFSETS2[m][0], OFFSETS2[m][1]);
}
}
// Test void ucal_getTimeZoneOffsetFromLocal(
// const UCalendar* cal,
// UTimeZoneLocalOption nonExistingTimeOpt,
// UTimeZoneLocalOption duplicatedTimeOpt,
// int32_t* rawOffset, int32_t* dstOffset, UErrorCode* status);
// with nonExistingTimeOpt=UCAL_TZ_LOCAL_DAYLIGHT and
// duplicatedTimeOpt=UCAL_TZ_LOCAL_DAYLIGHT
for (int m = 0; m < UPRV_LENGTHOF(DATES); m++) {
status = U_ZERO_ERROR;
ucal_setMillis(cal, MILLIS[m], &status);
if (U_FAILURE(status)) {
log_data_err("ucal_setMillis: %s\n", u_errorName(status));
}
ucal_getTimeZoneOffsetFromLocal(cal, UCAL_TZ_LOCAL_DAYLIGHT_LATTER, UCAL_TZ_LOCAL_DAYLIGHT_FORMER,
&rawOffset, &dstOffset, &status);
if (U_FAILURE(status)) {
log_err("ERROR: ucal_getTimeZoneOffsetFromLocal((%d-%d-%d %d:%d:0),"
"UCAL_TZ_LOCAL_DAYLIGHT_LATTER, UCAL_TZ_LOCAL_DAYLIGHT_FORMER: %s\n",
DATES[m][0], DATES[m][1], DATES[m][2], DATES[m][3], DATES[m][4],
u_errorName(status));
} else if (rawOffset != OFFSETS3[m][0] || dstOffset != OFFSETS3[m][1]) {
log_err("Bad offset returned at (%d-%d-%d %d:%d:0) "
"(wall/UCAL_TZ_LOCAL_DAYLIGHT_LATTER/UCAL_TZ_LOCAL_DAYLIGHT_FORMER) \n- Got: %d / %d "
" Expected %d / %d\n",
DATES[m][0], DATES[m][1], DATES[m][2], DATES[m][3], DATES[m][4],
rawOffset, dstOffset, OFFSETS3[m][0], OFFSETS3[m][1]);
}
}
// Test void ucal_getTimeZoneOffsetFromLocal(
// const UCalendar* cal,
// UTimeZoneLocalOption nonExistingTimeOpt,
// UTimeZoneLocalOption duplicatedTimeOpt,
// int32_t* rawOffset, int32_t* dstOffset, UErrorCode* status);
// with nonExistingTimeOpt=UCAL_TZ_LOCAL_FORMER and
// duplicatedTimeOpt=UCAL_TZ_LOCAL_LATTER
for (int m = 0; m < UPRV_LENGTHOF(DATES); m++) {
status = U_ZERO_ERROR;
ucal_setMillis(cal, MILLIS[m], &status);
if (U_FAILURE(status)) {
log_data_err("ucal_setMillis: %s\n", u_errorName(status));
}
ucal_getTimeZoneOffsetFromLocal(cal, UCAL_TZ_LOCAL_FORMER, UCAL_TZ_LOCAL_LATTER,
&rawOffset, &dstOffset, &status);
if (U_FAILURE(status)) {
log_err("ERROR: ucal_getTimeZoneOffsetFromLocal((%d-%d-%d %d:%d:0),"
"UCAL_TZ_LOCAL_FORMER, UCAL_TZ_LOCAL_LATTER: %s\n",
DATES[m][0], DATES[m][1], DATES[m][2], DATES[m][3], DATES[m][4],
u_errorName(status));
} else if (rawOffset != OFFSETS2[m][0] || dstOffset != OFFSETS2[m][1]) {
log_err("Bad offset returned at (%d-%d-%d %d:%d:0) "
"(wall/UCAL_TZ_LOCAL_FORMER/UCAL_TZ_LOCAL_LATTER) \n- Got: %d / %d "
" Expected %d / %d\n",
DATES[m][0], DATES[m][1], DATES[m][2], DATES[m][3], DATES[m][4],
rawOffset, dstOffset, OFFSETS2[m][0], OFFSETS2[m][1]);
}
}
// Test void ucal_getTimeZoneOffsetFromLocal(
// const UCalendar* cal,
// UTimeZoneLocalOption nonExistingTimeOpt,
// UTimeZoneLocalOption duplicatedTimeOpt,
// int32_t* rawOffset, int32_t* dstOffset, UErrorCode* status);
// with nonExistingTimeOpt=UCAL_TZ_LOCAL_LATTER and
// duplicatedTimeOpt=UCAL_TZ_LOCAL_FORMER
for (int m = 0; m < UPRV_LENGTHOF(DATES); m++) {
status = U_ZERO_ERROR;
ucal_setMillis(cal, MILLIS[m], &status);
if (U_FAILURE(status)) {
log_data_err("ucal_setMillis: %s\n", u_errorName(status));
}
ucal_getTimeZoneOffsetFromLocal(cal, UCAL_TZ_LOCAL_LATTER, UCAL_TZ_LOCAL_FORMER,
&rawOffset, &dstOffset, &status);
if (U_FAILURE(status)) {
log_err("ERROR: ucal_getTimeZoneOffsetFromLocal((%d-%d-%d %d:%d:0),"
"UCAL_TZ_LOCAL_LATTER, UCAL_TZ_LOCAL_FORMER: %s\n",
DATES[m][0], DATES[m][1], DATES[m][2], DATES[m][3], DATES[m][4],
u_errorName(status));
} else if (rawOffset != OFFSETS3[m][0] || dstOffset != OFFSETS3[m][1]) {
log_err("Bad offset returned at (%d-%d-%d %d:%d:0) "
"(wall/UCAL_TZ_LOCAL_LATTER/UCAL_TZ_LOCAL_FORMER) \n- Got: %d / %d "
" Expected %d / %d\n",
DATES[m][0], DATES[m][1], DATES[m][2], DATES[m][3], DATES[m][4],
rawOffset, dstOffset, OFFSETS3[m][0], OFFSETS3[m][1]);
}
}
ucal_close(cal);
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View file

@ -79,9 +79,9 @@ TimeZoneOffsetLocalTest::TestGetOffsetAroundTransition() {
// Expected offsets by void getOffset(UDate date, UBool local, int32_t& rawOffset,
// int32_t& dstOffset, UErrorCode& ec) with local=TRUE
// or void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
// or void getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingTimeOpt, UTimeZoneLocalOption duplicatedTimeOpt,
// int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) with
// nonExistingTimeOpt=kStandard/duplicatedTimeOpt=kStandard
// nonExistingTimeOpt=STANDARD_*/duplicatedTimeOpt=STANDARD_*
const int32_t OFFSETS2[NUM_DATES][2] = {
// April 2, 2006
{-8*HOUR, 0},
@ -98,9 +98,9 @@ TimeZoneOffsetLocalTest::TestGetOffsetAroundTransition() {
{-8*HOUR, 0},
};
// Expected offsets by void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt,
// int32_t duplicatedTimeOpt, int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) with
// nonExistingTimeOpt=kDaylight/duplicatedTimeOpt=kDaylight
// Expected offsets by void getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingTimeOpt,
// UTimeZoneLocalOption duplicatedTimeOpt, int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) with
// nonExistingTimeOpt=DAYLIGHT_*/duplicatedTimeOpt=DAYLIGHT_*
const int32_t OFFSETS3[][2] = {
// April 2, 2006
{-8*HOUR, 0},
@ -237,84 +237,84 @@ TimeZoneOffsetLocalTest::TestGetOffsetAroundTransition() {
}
}
// Test getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
// Test getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingTimeOpt, UTimeZoneLocalOption duplicatedTimeOpt,
// int32_t& rawOffset, int32_t& dstOffset, UErroCode& status)
// with nonExistingTimeOpt=kStandard/duplicatedTimeOpt=kStandard
// with nonExistingTimeOpt=STANDARD_FORMER/duplicatedTimeOpt=STANDARD_LATTER
for (int32_t i = 0; i < NUM_TIMEZONES; i++) {
for (int m = 0; m < NUM_DATES; m++) {
status = U_ZERO_ERROR;
TESTZONES[i]->getOffsetFromLocal(MILLIS[m], BasicTimeZone::kStandard, BasicTimeZone::kStandard,
TESTZONES[i]->getOffsetFromLocal(MILLIS[m], UCAL_TZ_LOCAL_STANDARD_FORMER, UCAL_TZ_LOCAL_STANDARD_LATTER,
rawOffset, dstOffset, status);
if (U_FAILURE(status)) {
errln((UnicodeString)"getOffsetFromLocal with kStandard/kStandard failed for TESTZONES[" + i + "]");
errln((UnicodeString)"getOffsetFromLocal with UCAL_TZ_LOCAL_STANDARD_FORMER/UCAL_TZ_LOCAL_STANDARD_LATTER failed for TESTZONES[" + i + "]");
} else if (rawOffset != OFFSETS2[m][0] || dstOffset != OFFSETS2[m][1]) {
dateStr.remove();
df.format(MILLIS[m], dateStr);
dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i + "] at "
+ dateStr + "(wall/kStandard/kStandard) - Got: "
+ dateStr + "(wall/STANDARD_FORMER/STANDARD_LATTER) - Got: "
+ rawOffset + "/" + dstOffset
+ " Expected: " + OFFSETS2[m][0] + "/" + OFFSETS2[m][1]);
}
}
}
// Test getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
// Test getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingTimeOpt, UTimeZoneLocalOption duplicatedTimeOpt,
// int32_t& rawOffset, int32_t& dstOffset, UErroCode& status)
// with nonExistingTimeOpt=kDaylight/duplicatedTimeOpt=kDaylight
// with nonExistingTimeOpt=DAYLIGHT_LATTER/duplicatedTimeOpt=DAYLIGHT_FORMER
for (int32_t i = 0; i < NUM_TIMEZONES; i++) {
for (int m = 0; m < NUM_DATES; m++) {
status = U_ZERO_ERROR;
TESTZONES[i]->getOffsetFromLocal(MILLIS[m], BasicTimeZone::kDaylight, BasicTimeZone::kDaylight,
TESTZONES[i]->getOffsetFromLocal(MILLIS[m], UCAL_TZ_LOCAL_DAYLIGHT_LATTER, UCAL_TZ_LOCAL_DAYLIGHT_FORMER,
rawOffset, dstOffset, status);
if (U_FAILURE(status)) {
errln((UnicodeString)"getOffsetFromLocal with kDaylight/kDaylight failed for TESTZONES[" + i + "]");
errln((UnicodeString)"getOffsetFromLocal with UCAL_TZ_LOCAL_DAYLIGHT_LATTER/UCAL_TZ_LOCAL_DAYLIGHT_FORMER failed for TESTZONES[" + i + "]");
} else if (rawOffset != OFFSETS3[m][0] || dstOffset != OFFSETS3[m][1]) {
dateStr.remove();
df.format(MILLIS[m], dateStr);
dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i + "] at "
+ dateStr + "(wall/kDaylight/kDaylight) - Got: "
+ dateStr + "(wall/DAYLIGHT_LATTER/DAYLIGHT_FORMER) - Got: "
+ rawOffset + "/" + dstOffset
+ " Expected: " + OFFSETS3[m][0] + "/" + OFFSETS3[m][1]);
}
}
}
// Test getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
// Test getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingTimeOpt, UTimeZoneLocalOption duplicatedTimeOpt,
// int32_t& rawOffset, int32_t& dstOffset, UErroCode& status)
// with nonExistingTimeOpt=kFormer/duplicatedTimeOpt=kLatter
// with nonExistingTimeOpt=FORMER/duplicatedTimeOpt=LATTER
for (int32_t i = 0; i < NUM_TIMEZONES; i++) {
for (int m = 0; m < NUM_DATES; m++) {
status = U_ZERO_ERROR;
TESTZONES[i]->getOffsetFromLocal(MILLIS[m], BasicTimeZone::kFormer, BasicTimeZone::kLatter,
TESTZONES[i]->getOffsetFromLocal(MILLIS[m], UCAL_TZ_LOCAL_FORMER, UCAL_TZ_LOCAL_LATTER,
rawOffset, dstOffset, status);
if (U_FAILURE(status)) {
errln((UnicodeString)"getOffsetFromLocal with kFormer/kLatter failed for TESTZONES[" + i + "]");
errln((UnicodeString)"getOffsetFromLocal with UCAL_TZ_LOCAL_FORMER/UCAL_TZ_LOCAL_LATTER failed for TESTZONES[" + i + "]");
} else if (rawOffset != OFFSETS2[m][0] || dstOffset != OFFSETS2[m][1]) {
dateStr.remove();
df.format(MILLIS[m], dateStr);
dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i + "] at "
+ dateStr + "(wall/kFormer/kLatter) - Got: "
+ dateStr + "(wall/FORMER/LATTER) - Got: "
+ rawOffset + "/" + dstOffset
+ " Expected: " + OFFSETS2[m][0] + "/" + OFFSETS2[m][1]);
}
}
}
// Test getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
// Test getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingTimeOpt, UTimeZoneLocalOption duplicatedTimeOpt,
// int32_t& rawOffset, int32_t& dstOffset, UErroCode& status)
// with nonExistingTimeOpt=kLatter/duplicatedTimeOpt=kFormer
// with nonExistingTimeOpt=LATTER/duplicatedTimeOpt=FORMER
for (int32_t i = 0; i < NUM_TIMEZONES; i++) {
for (int m = 0; m < NUM_DATES; m++) {
status = U_ZERO_ERROR;
TESTZONES[i]->getOffsetFromLocal(MILLIS[m], BasicTimeZone::kLatter, BasicTimeZone::kFormer,
TESTZONES[i]->getOffsetFromLocal(MILLIS[m], UCAL_TZ_LOCAL_LATTER, UCAL_TZ_LOCAL_FORMER,
rawOffset, dstOffset, status);
if (U_FAILURE(status)) {
errln((UnicodeString)"getOffsetFromLocal with kLatter/kFormer failed for TESTZONES[" + i + "]");
errln((UnicodeString)"getOffsetFromLocal with UCAL_TZ_LOCAL_LATTER/UCAL_TZ_LOCAL_FORMER failed for TESTZONES[" + i + "]");
} else if (rawOffset != OFFSETS3[m][0] || dstOffset != OFFSETS3[m][1]) {
dateStr.remove();
df.format(MILLIS[m], dateStr);
dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i + "] at "
+ dateStr + "(wall/kLatter/kFormer) - Got: "
+ dateStr + "(wall/LATTER/FORMER) - Got: "
+ rawOffset + "/" + dstOffset
+ " Expected: " + OFFSETS3[m][0] + "/" + OFFSETS3[m][1]);
}