зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1709867 - Add a ICU-only DateTimeInfo::timeZoneId method. r=anba,platform-i18n-reviewers,dminor
Differential Revision: https://phabricator.services.mozilla.com/D169611
This commit is contained in:
Родитель
8ae10544b1
Коммит
c46852b04b
|
@ -106,23 +106,7 @@ class TimeZone final {
|
|||
mTimeZone->getDisplayName(static_cast<bool>(aDaylightSavings),
|
||||
icu::TimeZone::LONG, icu::Locale(aLocale),
|
||||
displayName);
|
||||
|
||||
int32_t length = displayName.length();
|
||||
if (!aBuffer.reserve(AssertedCast<size_t>(length))) {
|
||||
return Err(ICUError::OutOfMemory);
|
||||
}
|
||||
|
||||
// Copy the display name.
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t written = displayName.extract(aBuffer.data(), length, status);
|
||||
if (!ICUSuccessForStringSpan(status)) {
|
||||
return Err(ToICUError(status));
|
||||
}
|
||||
MOZ_ASSERT(written == length);
|
||||
|
||||
aBuffer.written(written);
|
||||
|
||||
return Ok{};
|
||||
return FillBuffer(displayName, aBuffer);
|
||||
#else
|
||||
return FillBufferWithICUCall(
|
||||
aBuffer, [&](UChar* target, int32_t length, UErrorCode* status) {
|
||||
|
@ -134,6 +118,23 @@ class TimeZone final {
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the identifier for this time zone.
|
||||
*/
|
||||
template <typename B>
|
||||
ICUResult GetId(B& aBuffer) {
|
||||
#if MOZ_INTL_USE_ICU_CPP_TIMEZONE
|
||||
icu::UnicodeString id;
|
||||
mTimeZone->getID(id);
|
||||
return FillBuffer(id, aBuffer);
|
||||
#else
|
||||
return FillBufferWithICUCall(
|
||||
aBuffer, [&](UChar* target, int32_t length, UErrorCode* status) {
|
||||
return ucal_getTimeZoneID(mCalendar, target, length, status);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the buffer with the system's default IANA time zone identifier, e.g.
|
||||
* "America/Chicago".
|
||||
|
@ -225,6 +226,25 @@ class TimeZone final {
|
|||
static Result<SpanEnumeration<char>, ICUError> GetAvailableTimeZones();
|
||||
|
||||
private:
|
||||
template <typename B>
|
||||
static ICUResult FillBuffer(const icu::UnicodeString& aString, B& aBuffer) {
|
||||
int32_t length = aString.length();
|
||||
if (!aBuffer.reserve(AssertedCast<size_t>(length))) {
|
||||
return Err(ICUError::OutOfMemory);
|
||||
}
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t written = aString.extract(aBuffer.data(), length, status);
|
||||
if (!ICUSuccessForStringSpan(status)) {
|
||||
return Err(ToICUError(status));
|
||||
}
|
||||
MOZ_ASSERT(written == length);
|
||||
|
||||
aBuffer.written(written);
|
||||
|
||||
return Ok{};
|
||||
}
|
||||
|
||||
#if MOZ_INTL_USE_ICU_CPP_TIMEZONE
|
||||
UniquePtr<icu::TimeZone> mTimeZone = nullptr;
|
||||
#else
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
#include "util/Text.h"
|
||||
#include "vm/BooleanObject.h"
|
||||
#include "vm/DateObject.h"
|
||||
#include "vm/DateTime.h"
|
||||
#include "vm/ErrorObject.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/HelperThreads.h"
|
||||
|
@ -7959,7 +7960,7 @@ static bool GetICUOptions(JSContext* cx, unsigned argc, Value* vp) {
|
|||
|
||||
intl::FormatBuffer<char16_t, intl::INITIAL_CHAR_BUFFER_SIZE> buf(cx);
|
||||
|
||||
if (auto ok = mozilla::intl::TimeZone::GetDefaultTimeZone(buf); ok.isErr()) {
|
||||
if (auto ok = DateTimeInfo::timeZoneId(buf); ok.isErr()) {
|
||||
intl::ReportInternalError(cx, ok.unwrapErr());
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -402,13 +402,8 @@ bool js::intl_defaultTimeZone(JSContext* cx, unsigned argc, Value* vp) {
|
|||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
MOZ_ASSERT(args.length() == 0);
|
||||
|
||||
// The current default might be stale, because JS::ResetTimeZone() doesn't
|
||||
// immediately update ICU's default time zone. So perform an update if
|
||||
// needed.
|
||||
js::ResyncICUDefaultTimeZone();
|
||||
|
||||
FormatBuffer<char16_t, intl::INITIAL_CHAR_BUFFER_SIZE> timeZone(cx);
|
||||
auto result = mozilla::intl::TimeZone::GetDefaultTimeZone(timeZone);
|
||||
auto result = DateTimeInfo::timeZoneId(timeZone);
|
||||
if (result.isErr()) {
|
||||
intl::ReportInternalError(cx, result.unwrapErr());
|
||||
return false;
|
||||
|
@ -455,13 +450,8 @@ bool js::intl_isDefaultTimeZone(JSContext* cx, unsigned argc, Value* vp) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// The current default might be stale, because JS::ResetTimeZone() doesn't
|
||||
// immediately update ICU's default time zone. So perform an update if
|
||||
// needed.
|
||||
js::ResyncICUDefaultTimeZone();
|
||||
|
||||
FormatBuffer<char16_t, intl::INITIAL_CHAR_BUFFER_SIZE> chars(cx);
|
||||
auto result = mozilla::intl::TimeZone::GetDefaultTimeZone(chars);
|
||||
auto result = DateTimeInfo::timeZoneId(chars);
|
||||
if (result.isErr()) {
|
||||
intl::ReportInternalError(cx, result.unwrapErr());
|
||||
return false;
|
||||
|
|
|
@ -729,10 +729,6 @@ static bool ReadTimeZoneLink(std::string_view tz,
|
|||
# endif /* defined(XP_WIN) */
|
||||
#endif /* JS_HAS_INTL_API */
|
||||
|
||||
void js::ResyncICUDefaultTimeZone() {
|
||||
js::DateTimeInfo::resyncICUDefaultTimeZone();
|
||||
}
|
||||
|
||||
void js::DateTimeInfo::internalResyncICUDefaultTimeZone() {
|
||||
#if JS_HAS_INTL_API
|
||||
if (const char* tzenv = std::getenv("TZ")) {
|
||||
|
|
|
@ -15,9 +15,8 @@
|
|||
#include "threading/ExclusiveData.h"
|
||||
|
||||
#if JS_HAS_INTL_API
|
||||
namespace mozilla::intl {
|
||||
class TimeZone;
|
||||
}
|
||||
# include "mozilla/intl/ICU4CGlue.h"
|
||||
# include "mozilla/intl/TimeZone.h"
|
||||
#endif
|
||||
|
||||
namespace js {
|
||||
|
@ -62,15 +61,6 @@ enum class ResetTimeZoneMode : bool {
|
|||
*/
|
||||
extern void ResetTimeZoneInternal(ResetTimeZoneMode mode);
|
||||
|
||||
/**
|
||||
* ICU's default time zone, used for various date/time formatting operations
|
||||
* that include the local time in the representation, is allowed to go stale
|
||||
* for unfortunate performance reasons. Call this function when an up-to-date
|
||||
* default time zone is required, to resync ICU's default time zone with
|
||||
* reality.
|
||||
*/
|
||||
extern void ResyncICUDefaultTimeZone();
|
||||
|
||||
/**
|
||||
* Stores date/time information, particularly concerning the current local
|
||||
* time zone, and implements a small cache for daylight saving time offset
|
||||
|
@ -186,6 +176,16 @@ class DateTimeInfo {
|
|||
return guard->internalTimeZoneDisplayName(buf, buflen, utcMilliseconds,
|
||||
locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the identifier for the current time zone to the provided resizable
|
||||
* buffer.
|
||||
*/
|
||||
template <typename B>
|
||||
static mozilla::intl::ICUResult timeZoneId(B& buffer) {
|
||||
auto guard = acquireLockWithValidTimeZone();
|
||||
return guard->timeZone()->GetId(buffer);
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* Return the local time zone adjustment (ES2019 20.3.1.7) as computed by
|
||||
|
@ -197,21 +197,14 @@ class DateTimeInfo {
|
|||
#endif /* JS_HAS_INTL_API */
|
||||
|
||||
private:
|
||||
// The two methods below should only be called via js::ResetTimeZoneInternal()
|
||||
// and js::ResyncICUDefaultTimeZone().
|
||||
// The method below should only be called via js::ResetTimeZoneInternal().
|
||||
friend void js::ResetTimeZoneInternal(ResetTimeZoneMode);
|
||||
friend void js::ResyncICUDefaultTimeZone();
|
||||
|
||||
static void resetTimeZone(ResetTimeZoneMode mode) {
|
||||
auto guard = instance->lock();
|
||||
guard->internalResetTimeZone(mode);
|
||||
}
|
||||
|
||||
static void resyncICUDefaultTimeZone() {
|
||||
auto guard = acquireLockWithValidTimeZone();
|
||||
(void)guard;
|
||||
}
|
||||
|
||||
struct RangeCache {
|
||||
// Start and end offsets in seconds describing the current and the
|
||||
// last cached range.
|
||||
|
|
Загрузка…
Ссылка в новой задаче