mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1519167 - Part 30: Add methods to retrieve time zone transitions and utf-offsets from local time. r=spidermonkey-reviewers,allstarschh
The `GetNamedTimeZoneEpochNanoseconds`, `GetNamedTimeZoneNextTransition`, and `GetNamedTimeZonePreviousTransition` abstract operations from the Temporal API proposal require these additional methods. Differential Revision: https://phabricator.services.mozilla.com/D174287
This commit is contained in:
parent
8611b683d5
commit
a5486477fc
@ -169,10 +169,29 @@ Result<int32_t, ICUError> TimeZone::GetUTCOffsetMs(int64_t aLocalMilliseconds) {
|
||||
// time starts or the time zone offset is increased due to a time zone rule
|
||||
// change), t_local must be interpreted using the time zone offset before the
|
||||
// transition.
|
||||
constexpr UTimeZoneLocalOption skippedTime = UCAL_TZ_LOCAL_FORMER;
|
||||
constexpr UTimeZoneLocalOption repeatedTime = UCAL_TZ_LOCAL_FORMER;
|
||||
constexpr LocalOption skippedTime = LocalOption::Former;
|
||||
constexpr LocalOption repeatedTime = LocalOption::Former;
|
||||
|
||||
return GetUTCOffsetMs(aLocalMilliseconds, skippedTime, repeatedTime);
|
||||
}
|
||||
|
||||
static UTimeZoneLocalOption ToUTimeZoneLocalOption(
|
||||
TimeZone::LocalOption aOption) {
|
||||
switch (aOption) {
|
||||
case TimeZone::LocalOption::Former:
|
||||
return UTimeZoneLocalOption::UCAL_TZ_LOCAL_FORMER;
|
||||
case TimeZone::LocalOption::Latter:
|
||||
return UTimeZoneLocalOption::UCAL_TZ_LOCAL_LATTER;
|
||||
}
|
||||
MOZ_CRASH("Unexpected TimeZone::LocalOption");
|
||||
}
|
||||
|
||||
Result<int32_t, ICUError> TimeZone::GetUTCOffsetMs(int64_t aLocalMilliseconds,
|
||||
LocalOption aSkippedTime,
|
||||
LocalOption aRepeatedTime) {
|
||||
UDate date = UDate(aLocalMilliseconds);
|
||||
UTimeZoneLocalOption skippedTime = ToUTimeZoneLocalOption(aSkippedTime);
|
||||
UTimeZoneLocalOption repeatedTime = ToUTimeZoneLocalOption(aRepeatedTime);
|
||||
|
||||
#if MOZ_INTL_USE_ICU_CPP_TIMEZONE
|
||||
int32_t rawOffset, dstOffset;
|
||||
@ -208,6 +227,66 @@ Result<int32_t, ICUError> TimeZone::GetUTCOffsetMs(int64_t aLocalMilliseconds) {
|
||||
#endif
|
||||
}
|
||||
|
||||
Result<Maybe<int64_t>, ICUError> TimeZone::GetPreviousTransition(
|
||||
int64_t aUTCMilliseconds) {
|
||||
UDate date = UDate(aUTCMilliseconds);
|
||||
|
||||
#if MOZ_INTL_USE_ICU_CPP_TIMEZONE
|
||||
// All ICU TimeZone classes derive from BasicTimeZone, so we can safely
|
||||
// perform the static_cast.
|
||||
auto* basicTz = static_cast<icu::BasicTimeZone*>(mTimeZone.get());
|
||||
|
||||
constexpr bool inclusive = false;
|
||||
icu::TimeZoneTransition transition;
|
||||
if (!basicTz->getPreviousTransition(date, inclusive, transition)) {
|
||||
return Maybe<int64_t>();
|
||||
}
|
||||
return Some(int64_t(transition.getTime()));
|
||||
#else
|
||||
UDate transition = 0;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
bool found = ucal_getTimeZoneTransitionDate(
|
||||
mCalendar, UCAL_TZ_TRANSITION_PREVIOUS, &transition, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
return Err(ToICUError(status));
|
||||
}
|
||||
if (!found) {
|
||||
return Maybe<int64_t>();
|
||||
}
|
||||
return Some(int64_t(transition));
|
||||
#endif
|
||||
}
|
||||
|
||||
Result<Maybe<int64_t>, ICUError> TimeZone::GetNextTransition(
|
||||
int64_t aUTCMilliseconds) {
|
||||
UDate date = UDate(aUTCMilliseconds);
|
||||
|
||||
#if MOZ_INTL_USE_ICU_CPP_TIMEZONE
|
||||
// All ICU TimeZone classes derive from BasicTimeZone, so we can safely
|
||||
// perform the static_cast.
|
||||
auto* basicTz = static_cast<icu::BasicTimeZone*>(mTimeZone.get());
|
||||
|
||||
constexpr bool inclusive = false;
|
||||
icu::TimeZoneTransition transition;
|
||||
if (!basicTz->getNextTransition(date, inclusive, transition)) {
|
||||
return Maybe<int64_t>();
|
||||
}
|
||||
return Some(int64_t(transition.getTime()));
|
||||
#else
|
||||
UDate transition = 0;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
bool found = ucal_getTimeZoneTransitionDate(
|
||||
mCalendar, UCAL_TZ_TRANSITION_NEXT, &transition, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
return Err(ToICUError(status));
|
||||
}
|
||||
if (!found) {
|
||||
return Maybe<int64_t>();
|
||||
}
|
||||
return Some(int64_t(transition));
|
||||
#endif
|
||||
}
|
||||
|
||||
using TimeZoneIdentifierVector =
|
||||
Vector<char16_t, TimeZone::TimeZoneIdentifierLength>;
|
||||
|
||||
|
@ -93,6 +93,41 @@ class TimeZone final {
|
||||
*/
|
||||
Result<int32_t, ICUError> GetUTCOffsetMs(int64_t aLocalMilliseconds);
|
||||
|
||||
enum class LocalOption {
|
||||
/**
|
||||
* The input is interpreted as local time before a time zone transition.
|
||||
*/
|
||||
Former,
|
||||
|
||||
/**
|
||||
* The input is interpreted as local time after a time zone transition.
|
||||
*/
|
||||
Latter,
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the UTC offset in milliseconds at the given local time.
|
||||
*
|
||||
* `aSkippedTime` and `aRepeatedTime` select how to interpret skipped and
|
||||
* repeated local times.
|
||||
*/
|
||||
Result<int32_t, ICUError> GetUTCOffsetMs(int64_t aLocalMilliseconds,
|
||||
LocalOption aSkippedTime,
|
||||
LocalOption aRepeatedTime);
|
||||
|
||||
/**
|
||||
* Return the previous time zone transition before the given UTC time. If no
|
||||
* transition was found, return Nothing.
|
||||
*/
|
||||
Result<Maybe<int64_t>, ICUError> GetPreviousTransition(
|
||||
int64_t aUTCMilliseconds);
|
||||
|
||||
/**
|
||||
* Return the next time zone transition after the given UTC time. If no
|
||||
* transition was found, return Nothing.
|
||||
*/
|
||||
Result<Maybe<int64_t>, ICUError> GetNextTransition(int64_t aUTCMilliseconds);
|
||||
|
||||
enum class DaylightSavings : bool { No, Yes };
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user