630 lines
19 KiB
C++
630 lines
19 KiB
C++
// © 2016 and later: Unicode, Inc. and others.
|
|
// License & terms of use: http://www.unicode.org/copyright.html
|
|
/*
|
|
*******************************************************************************
|
|
* Copyright (C) 2007-2012, International Business Machines Corporation and
|
|
* others. All Rights Reserved.
|
|
*******************************************************************************
|
|
*/
|
|
|
|
#include "utypeinfo.h" // for 'typeid' to work
|
|
|
|
#include "unicode/utypes.h"
|
|
|
|
#if !UCONFIG_NO_FORMATTING
|
|
|
|
#include "unicode/tzrule.h"
|
|
#include "unicode/ucal.h"
|
|
#include "gregoimp.h"
|
|
#include "cmemory.h"
|
|
#include "uarrsort.h"
|
|
|
|
U_CDECL_BEGIN
|
|
// UComparator function for sorting start times
|
|
static int32_t U_CALLCONV
|
|
compareDates(const void * /*context*/, const void *left, const void *right) {
|
|
UDate l = *((UDate*)left);
|
|
UDate r = *((UDate*)right);
|
|
int32_t res = l < r ? -1 : (l == r ? 0 : 1);
|
|
return res;
|
|
}
|
|
U_CDECL_END
|
|
|
|
U_NAMESPACE_BEGIN
|
|
|
|
TimeZoneRule::TimeZoneRule(const UnicodeString& name, int32_t rawOffset, int32_t dstSavings)
|
|
: UObject(), fName(name), fRawOffset(rawOffset), fDSTSavings(dstSavings) {
|
|
}
|
|
|
|
TimeZoneRule::TimeZoneRule(const TimeZoneRule& source)
|
|
: UObject(source), fName(source.fName), fRawOffset(source.fRawOffset), fDSTSavings(source.fDSTSavings) {
|
|
}
|
|
|
|
TimeZoneRule::~TimeZoneRule() {
|
|
}
|
|
|
|
TimeZoneRule&
|
|
TimeZoneRule::operator=(const TimeZoneRule& right) {
|
|
if (this != &right) {
|
|
fName = right.fName;
|
|
fRawOffset = right.fRawOffset;
|
|
fDSTSavings = right.fDSTSavings;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
bool
|
|
TimeZoneRule::operator==(const TimeZoneRule& that) const {
|
|
return ((this == &that) ||
|
|
(typeid(*this) == typeid(that) &&
|
|
fName == that.fName &&
|
|
fRawOffset == that.fRawOffset &&
|
|
fDSTSavings == that.fDSTSavings));
|
|
}
|
|
|
|
bool
|
|
TimeZoneRule::operator!=(const TimeZoneRule& that) const {
|
|
return !operator==(that);
|
|
}
|
|
|
|
UnicodeString&
|
|
TimeZoneRule::getName(UnicodeString& name) const {
|
|
name = fName;
|
|
return name;
|
|
}
|
|
|
|
int32_t
|
|
TimeZoneRule::getRawOffset(void) const {
|
|
return fRawOffset;
|
|
}
|
|
|
|
int32_t
|
|
TimeZoneRule::getDSTSavings(void) const {
|
|
return fDSTSavings;
|
|
}
|
|
|
|
UBool
|
|
TimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
|
|
return ((this == &other) ||
|
|
(typeid(*this) == typeid(other) &&
|
|
fRawOffset == other.fRawOffset &&
|
|
fDSTSavings == other.fDSTSavings));
|
|
}
|
|
|
|
|
|
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(InitialTimeZoneRule)
|
|
|
|
InitialTimeZoneRule::InitialTimeZoneRule(const UnicodeString& name,
|
|
int32_t rawOffset,
|
|
int32_t dstSavings)
|
|
: TimeZoneRule(name, rawOffset, dstSavings) {
|
|
}
|
|
|
|
InitialTimeZoneRule::InitialTimeZoneRule(const InitialTimeZoneRule& source)
|
|
: TimeZoneRule(source) {
|
|
}
|
|
|
|
InitialTimeZoneRule::~InitialTimeZoneRule() {
|
|
}
|
|
|
|
InitialTimeZoneRule*
|
|
InitialTimeZoneRule::clone() const {
|
|
return new InitialTimeZoneRule(*this);
|
|
}
|
|
|
|
InitialTimeZoneRule&
|
|
InitialTimeZoneRule::operator=(const InitialTimeZoneRule& right) {
|
|
if (this != &right) {
|
|
TimeZoneRule::operator=(right);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
bool
|
|
InitialTimeZoneRule::operator==(const TimeZoneRule& that) const {
|
|
return ((this == &that) ||
|
|
(typeid(*this) == typeid(that) &&
|
|
TimeZoneRule::operator==(that)));
|
|
}
|
|
|
|
bool
|
|
InitialTimeZoneRule::operator!=(const TimeZoneRule& that) const {
|
|
return !operator==(that);
|
|
}
|
|
|
|
UBool
|
|
InitialTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
|
|
if (this == &other) {
|
|
return true;
|
|
}
|
|
if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == false) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
UBool
|
|
InitialTimeZoneRule::getFirstStart(int32_t /*prevRawOffset*/,
|
|
int32_t /*prevDSTSavings*/,
|
|
UDate& /*result*/) const {
|
|
return false;
|
|
}
|
|
|
|
UBool
|
|
InitialTimeZoneRule::getFinalStart(int32_t /*prevRawOffset*/,
|
|
int32_t /*prevDSTSavings*/,
|
|
UDate& /*result*/) const {
|
|
return false;
|
|
}
|
|
|
|
UBool
|
|
InitialTimeZoneRule::getNextStart(UDate /*base*/,
|
|
int32_t /*prevRawOffset*/,
|
|
int32_t /*prevDSTSavings*/,
|
|
UBool /*inclusive*/,
|
|
UDate& /*result*/) const {
|
|
return false;
|
|
}
|
|
|
|
UBool
|
|
InitialTimeZoneRule::getPreviousStart(UDate /*base*/,
|
|
int32_t /*prevRawOffset*/,
|
|
int32_t /*prevDSTSavings*/,
|
|
UBool /*inclusive*/,
|
|
UDate& /*result*/) const {
|
|
return false;
|
|
}
|
|
|
|
|
|
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(AnnualTimeZoneRule)
|
|
|
|
const int32_t AnnualTimeZoneRule::MAX_YEAR = 0x7FFFFFFF; /* max signed int32 */
|
|
|
|
AnnualTimeZoneRule::AnnualTimeZoneRule(const UnicodeString& name,
|
|
int32_t rawOffset,
|
|
int32_t dstSavings,
|
|
const DateTimeRule& dateTimeRule,
|
|
int32_t startYear,
|
|
int32_t endYear)
|
|
: TimeZoneRule(name, rawOffset, dstSavings), fDateTimeRule(new DateTimeRule(dateTimeRule)),
|
|
fStartYear(startYear), fEndYear(endYear) {
|
|
}
|
|
|
|
AnnualTimeZoneRule::AnnualTimeZoneRule(const UnicodeString& name,
|
|
int32_t rawOffset,
|
|
int32_t dstSavings,
|
|
DateTimeRule* dateTimeRule,
|
|
int32_t startYear,
|
|
int32_t endYear)
|
|
: TimeZoneRule(name, rawOffset, dstSavings), fDateTimeRule(dateTimeRule),
|
|
fStartYear(startYear), fEndYear(endYear) {
|
|
}
|
|
|
|
AnnualTimeZoneRule::AnnualTimeZoneRule(const AnnualTimeZoneRule& source)
|
|
: TimeZoneRule(source), fDateTimeRule(new DateTimeRule(*(source.fDateTimeRule))),
|
|
fStartYear(source.fStartYear), fEndYear(source.fEndYear) {
|
|
}
|
|
|
|
AnnualTimeZoneRule::~AnnualTimeZoneRule() {
|
|
delete fDateTimeRule;
|
|
}
|
|
|
|
AnnualTimeZoneRule*
|
|
AnnualTimeZoneRule::clone(void) const {
|
|
return new AnnualTimeZoneRule(*this);
|
|
}
|
|
|
|
AnnualTimeZoneRule&
|
|
AnnualTimeZoneRule::operator=(const AnnualTimeZoneRule& right) {
|
|
if (this != &right) {
|
|
TimeZoneRule::operator=(right);
|
|
delete fDateTimeRule;
|
|
fDateTimeRule = right.fDateTimeRule->clone();
|
|
fStartYear = right.fStartYear;
|
|
fEndYear = right.fEndYear;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
bool
|
|
AnnualTimeZoneRule::operator==(const TimeZoneRule& that) const {
|
|
if (this == &that) {
|
|
return true;
|
|
}
|
|
if (typeid(*this) != typeid(that)) {
|
|
return false;
|
|
}
|
|
AnnualTimeZoneRule *atzr = (AnnualTimeZoneRule*)&that;
|
|
return (*fDateTimeRule == *(atzr->fDateTimeRule) &&
|
|
fStartYear == atzr->fStartYear &&
|
|
fEndYear == atzr->fEndYear);
|
|
}
|
|
|
|
bool
|
|
AnnualTimeZoneRule::operator!=(const TimeZoneRule& that) const {
|
|
return !operator==(that);
|
|
}
|
|
|
|
const DateTimeRule*
|
|
AnnualTimeZoneRule::getRule() const {
|
|
return fDateTimeRule;
|
|
}
|
|
|
|
int32_t
|
|
AnnualTimeZoneRule::getStartYear() const {
|
|
return fStartYear;
|
|
}
|
|
|
|
int32_t
|
|
AnnualTimeZoneRule::getEndYear() const {
|
|
return fEndYear;
|
|
}
|
|
|
|
UBool
|
|
AnnualTimeZoneRule::getStartInYear(int32_t year,
|
|
int32_t prevRawOffset,
|
|
int32_t prevDSTSavings,
|
|
UDate &result) const {
|
|
if (year < fStartYear || year > fEndYear) {
|
|
return false;
|
|
}
|
|
double ruleDay;
|
|
DateTimeRule::DateRuleType type = fDateTimeRule->getDateRuleType();
|
|
if (type == DateTimeRule::DOM) {
|
|
ruleDay = Grego::fieldsToDay(year, fDateTimeRule->getRuleMonth(), fDateTimeRule->getRuleDayOfMonth());
|
|
} else {
|
|
UBool after = true;
|
|
if (type == DateTimeRule::DOW) {
|
|
// Normalize DOW rule into DOW_GEQ_DOM or DOW_LEQ_DOM
|
|
int32_t weeks = fDateTimeRule->getRuleWeekInMonth();
|
|
if (weeks > 0) {
|
|
ruleDay = Grego::fieldsToDay(year, fDateTimeRule->getRuleMonth(), 1);
|
|
ruleDay += 7 * (weeks - 1);
|
|
} else {
|
|
after = false;
|
|
ruleDay = Grego::fieldsToDay(year, fDateTimeRule->getRuleMonth(),
|
|
Grego::monthLength(year, fDateTimeRule->getRuleMonth()));
|
|
ruleDay += 7 * (weeks + 1);
|
|
}
|
|
} else {
|
|
int32_t month = fDateTimeRule->getRuleMonth();
|
|
int32_t dom = fDateTimeRule->getRuleDayOfMonth();
|
|
if (type == DateTimeRule::DOW_LEQ_DOM) {
|
|
after = false;
|
|
// Handle Feb <=29
|
|
if (month == UCAL_FEBRUARY && dom == 29 && !Grego::isLeapYear(year)) {
|
|
dom--;
|
|
}
|
|
}
|
|
ruleDay = Grego::fieldsToDay(year, month, dom);
|
|
}
|
|
int32_t dow = Grego::dayOfWeek(ruleDay);
|
|
int32_t delta = fDateTimeRule->getRuleDayOfWeek() - dow;
|
|
if (after) {
|
|
delta = delta < 0 ? delta + 7 : delta;
|
|
} else {
|
|
delta = delta > 0 ? delta - 7 : delta;
|
|
}
|
|
ruleDay += delta;
|
|
}
|
|
|
|
result = ruleDay*U_MILLIS_PER_DAY + fDateTimeRule->getRuleMillisInDay();
|
|
if (fDateTimeRule->getTimeRuleType() != DateTimeRule::UTC_TIME) {
|
|
result -= prevRawOffset;
|
|
}
|
|
if (fDateTimeRule->getTimeRuleType() == DateTimeRule::WALL_TIME) {
|
|
result -= prevDSTSavings;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
UBool
|
|
AnnualTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
|
|
if (this == &other) {
|
|
return true;
|
|
}
|
|
if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == false) {
|
|
return false;
|
|
}
|
|
AnnualTimeZoneRule* that = (AnnualTimeZoneRule*)&other;
|
|
return (*fDateTimeRule == *(that->fDateTimeRule) &&
|
|
fStartYear == that->fStartYear &&
|
|
fEndYear == that->fEndYear);
|
|
}
|
|
|
|
UBool
|
|
AnnualTimeZoneRule::getFirstStart(int32_t prevRawOffset,
|
|
int32_t prevDSTSavings,
|
|
UDate& result) const {
|
|
return getStartInYear(fStartYear, prevRawOffset, prevDSTSavings, result);
|
|
}
|
|
|
|
UBool
|
|
AnnualTimeZoneRule::getFinalStart(int32_t prevRawOffset,
|
|
int32_t prevDSTSavings,
|
|
UDate& result) const {
|
|
if (fEndYear == MAX_YEAR) {
|
|
return false;
|
|
}
|
|
return getStartInYear(fEndYear, prevRawOffset, prevDSTSavings, result);
|
|
}
|
|
|
|
UBool
|
|
AnnualTimeZoneRule::getNextStart(UDate base,
|
|
int32_t prevRawOffset,
|
|
int32_t prevDSTSavings,
|
|
UBool inclusive,
|
|
UDate& result) const {
|
|
int32_t year, month, dom, dow, doy, mid;
|
|
Grego::timeToFields(base, year, month, dom, dow, doy, mid);
|
|
if (year < fStartYear) {
|
|
return getFirstStart(prevRawOffset, prevDSTSavings, result);
|
|
}
|
|
UDate tmp;
|
|
if (getStartInYear(year, prevRawOffset, prevDSTSavings, tmp)) {
|
|
if (tmp < base || (!inclusive && (tmp == base))) {
|
|
// Return the next one
|
|
return getStartInYear(year + 1, prevRawOffset, prevDSTSavings, result);
|
|
} else {
|
|
result = tmp;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
UBool
|
|
AnnualTimeZoneRule::getPreviousStart(UDate base,
|
|
int32_t prevRawOffset,
|
|
int32_t prevDSTSavings,
|
|
UBool inclusive,
|
|
UDate& result) const {
|
|
int32_t year, month, dom, dow, doy, mid;
|
|
Grego::timeToFields(base, year, month, dom, dow, doy, mid);
|
|
if (year > fEndYear) {
|
|
return getFinalStart(prevRawOffset, prevDSTSavings, result);
|
|
}
|
|
UDate tmp;
|
|
if (getStartInYear(year, prevRawOffset, prevDSTSavings, tmp)) {
|
|
if (tmp > base || (!inclusive && (tmp == base))) {
|
|
// Return the previous one
|
|
return getStartInYear(year - 1, prevRawOffset, prevDSTSavings, result);
|
|
} else {
|
|
result = tmp;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeArrayTimeZoneRule)
|
|
|
|
TimeArrayTimeZoneRule::TimeArrayTimeZoneRule(const UnicodeString& name,
|
|
int32_t rawOffset,
|
|
int32_t dstSavings,
|
|
const UDate* startTimes,
|
|
int32_t numStartTimes,
|
|
DateTimeRule::TimeRuleType timeRuleType)
|
|
: TimeZoneRule(name, rawOffset, dstSavings), fTimeRuleType(timeRuleType),
|
|
fStartTimes(NULL) {
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
initStartTimes(startTimes, numStartTimes, status);
|
|
//TODO - status?
|
|
}
|
|
|
|
|
|
TimeArrayTimeZoneRule::TimeArrayTimeZoneRule(const TimeArrayTimeZoneRule& source)
|
|
: TimeZoneRule(source), fTimeRuleType(source.fTimeRuleType), fStartTimes(NULL) {
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
initStartTimes(source.fStartTimes, source.fNumStartTimes, status);
|
|
//TODO - status?
|
|
}
|
|
|
|
|
|
TimeArrayTimeZoneRule::~TimeArrayTimeZoneRule() {
|
|
if (fStartTimes != NULL && fStartTimes != fLocalStartTimes) {
|
|
uprv_free(fStartTimes);
|
|
}
|
|
}
|
|
|
|
TimeArrayTimeZoneRule*
|
|
TimeArrayTimeZoneRule::clone(void) const {
|
|
return new TimeArrayTimeZoneRule(*this);
|
|
}
|
|
|
|
|
|
TimeArrayTimeZoneRule&
|
|
TimeArrayTimeZoneRule::operator=(const TimeArrayTimeZoneRule& right) {
|
|
if (this != &right) {
|
|
TimeZoneRule::operator=(right);
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
initStartTimes(right.fStartTimes, right.fNumStartTimes, status);
|
|
//TODO - status?
|
|
fTimeRuleType = right.fTimeRuleType;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
bool
|
|
TimeArrayTimeZoneRule::operator==(const TimeZoneRule& that) const {
|
|
if (this == &that) {
|
|
return true;
|
|
}
|
|
if (typeid(*this) != typeid(that) || !TimeZoneRule::operator==(that)) {
|
|
return false;
|
|
}
|
|
TimeArrayTimeZoneRule *tatzr = (TimeArrayTimeZoneRule*)&that;
|
|
if (fTimeRuleType != tatzr->fTimeRuleType ||
|
|
fNumStartTimes != tatzr->fNumStartTimes) {
|
|
return false;
|
|
}
|
|
// Compare start times
|
|
bool res = true;
|
|
for (int32_t i = 0; i < fNumStartTimes; i++) {
|
|
if (fStartTimes[i] != tatzr->fStartTimes[i]) {
|
|
res = false;
|
|
break;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
bool
|
|
TimeArrayTimeZoneRule::operator!=(const TimeZoneRule& that) const {
|
|
return !operator==(that);
|
|
}
|
|
|
|
DateTimeRule::TimeRuleType
|
|
TimeArrayTimeZoneRule::getTimeType(void) const {
|
|
return fTimeRuleType;
|
|
}
|
|
|
|
UBool
|
|
TimeArrayTimeZoneRule::getStartTimeAt(int32_t index, UDate& result) const {
|
|
if (index >= fNumStartTimes || index < 0) {
|
|
return false;
|
|
}
|
|
result = fStartTimes[index];
|
|
return true;
|
|
}
|
|
|
|
int32_t
|
|
TimeArrayTimeZoneRule::countStartTimes(void) const {
|
|
return fNumStartTimes;
|
|
}
|
|
|
|
UBool
|
|
TimeArrayTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
|
|
if (this == &other) {
|
|
return true;
|
|
}
|
|
if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == false) {
|
|
return false;
|
|
}
|
|
TimeArrayTimeZoneRule* that = (TimeArrayTimeZoneRule*)&other;
|
|
if (fTimeRuleType != that->fTimeRuleType ||
|
|
fNumStartTimes != that->fNumStartTimes) {
|
|
return false;
|
|
}
|
|
// Compare start times
|
|
UBool res = true;
|
|
for (int32_t i = 0; i < fNumStartTimes; i++) {
|
|
if (fStartTimes[i] != that->fStartTimes[i]) {
|
|
res = false;
|
|
break;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
UBool
|
|
TimeArrayTimeZoneRule::getFirstStart(int32_t prevRawOffset,
|
|
int32_t prevDSTSavings,
|
|
UDate& result) const {
|
|
if (fNumStartTimes <= 0 || fStartTimes == NULL) {
|
|
return false;
|
|
}
|
|
result = getUTC(fStartTimes[0], prevRawOffset, prevDSTSavings);
|
|
return true;
|
|
}
|
|
|
|
UBool
|
|
TimeArrayTimeZoneRule::getFinalStart(int32_t prevRawOffset,
|
|
int32_t prevDSTSavings,
|
|
UDate& result) const {
|
|
if (fNumStartTimes <= 0 || fStartTimes == NULL) {
|
|
return false;
|
|
}
|
|
result = getUTC(fStartTimes[fNumStartTimes - 1], prevRawOffset, prevDSTSavings);
|
|
return true;
|
|
}
|
|
|
|
UBool
|
|
TimeArrayTimeZoneRule::getNextStart(UDate base,
|
|
int32_t prevRawOffset,
|
|
int32_t prevDSTSavings,
|
|
UBool inclusive,
|
|
UDate& result) const {
|
|
int32_t i = fNumStartTimes - 1;
|
|
for (; i >= 0; i--) {
|
|
UDate time = getUTC(fStartTimes[i], prevRawOffset, prevDSTSavings);
|
|
if (time < base || (!inclusive && time == base)) {
|
|
break;
|
|
}
|
|
result = time;
|
|
}
|
|
if (i == fNumStartTimes - 1) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
UBool
|
|
TimeArrayTimeZoneRule::getPreviousStart(UDate base,
|
|
int32_t prevRawOffset,
|
|
int32_t prevDSTSavings,
|
|
UBool inclusive,
|
|
UDate& result) const {
|
|
int32_t i = fNumStartTimes - 1;
|
|
for (; i >= 0; i--) {
|
|
UDate time = getUTC(fStartTimes[i], prevRawOffset, prevDSTSavings);
|
|
if (time < base || (inclusive && time == base)) {
|
|
result = time;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
// ---- private methods ------
|
|
|
|
UBool
|
|
TimeArrayTimeZoneRule::initStartTimes(const UDate source[], int32_t size, UErrorCode& status) {
|
|
// Free old array
|
|
if (fStartTimes != NULL && fStartTimes != fLocalStartTimes) {
|
|
uprv_free(fStartTimes);
|
|
}
|
|
// Allocate new one if needed
|
|
if (size > TIMEARRAY_STACK_BUFFER_SIZE) {
|
|
fStartTimes = (UDate*)uprv_malloc(sizeof(UDate)*size);
|
|
if (fStartTimes == NULL) {
|
|
status = U_MEMORY_ALLOCATION_ERROR;
|
|
fNumStartTimes = 0;
|
|
return false;
|
|
}
|
|
} else {
|
|
fStartTimes = (UDate*)fLocalStartTimes;
|
|
}
|
|
uprv_memcpy(fStartTimes, source, sizeof(UDate)*size);
|
|
fNumStartTimes = size;
|
|
// Sort dates
|
|
uprv_sortArray(fStartTimes, fNumStartTimes, (int32_t)sizeof(UDate), compareDates, NULL, true, &status);
|
|
if (U_FAILURE(status)) {
|
|
if (fStartTimes != NULL && fStartTimes != fLocalStartTimes) {
|
|
uprv_free(fStartTimes);
|
|
}
|
|
fNumStartTimes = 0;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
UDate
|
|
TimeArrayTimeZoneRule::getUTC(UDate time, int32_t raw, int32_t dst) const {
|
|
if (fTimeRuleType != DateTimeRule::UTC_TIME) {
|
|
time -= raw;
|
|
}
|
|
if (fTimeRuleType == DateTimeRule::WALL_TIME) {
|
|
time -= dst;
|
|
}
|
|
return time;
|
|
}
|
|
|
|
U_NAMESPACE_END
|
|
|
|
#endif /* #if !UCONFIG_NO_FORMATTING */
|
|
|
|
//eof
|
|
|