From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- intl/components/src/Calendar.cpp | 172 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 intl/components/src/Calendar.cpp (limited to 'intl/components/src/Calendar.cpp') diff --git a/intl/components/src/Calendar.cpp b/intl/components/src/Calendar.cpp new file mode 100644 index 0000000000..d44dedaaae --- /dev/null +++ b/intl/components/src/Calendar.cpp @@ -0,0 +1,172 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/intl/Calendar.h" + +#include "unicode/ucal.h" +#include "unicode/uloc.h" +#include "unicode/utypes.h" + +namespace mozilla::intl { + +/* static */ +Result, ICUError> Calendar::TryCreate( + const char* aLocale, Maybe> aTimeZoneOverride) { + UErrorCode status = U_ZERO_ERROR; + const UChar* zoneID = nullptr; + int32_t zoneIDLen = 0; + if (aTimeZoneOverride) { + zoneIDLen = static_cast(aTimeZoneOverride->Length()); + zoneID = aTimeZoneOverride->Elements(); + } + + UCalendar* calendar = + ucal_open(zoneID, zoneIDLen, aLocale, UCAL_DEFAULT, &status); + + if (U_FAILURE(status)) { + return Err(ToICUError(status)); + } + + return MakeUnique(calendar); +} + +Result, ICUError> Calendar::GetBcp47Type() { + UErrorCode status = U_ZERO_ERROR; + const char* oldType = ucal_getType(mCalendar, &status); + if (U_FAILURE(status)) { + return Err(ToICUError(status)); + } + const char* bcp47Type = uloc_toUnicodeLocaleType("calendar", oldType); + + if (!bcp47Type) { + return Err(ICUError::InternalError); + } + + return MakeStringSpan(bcp47Type); +} + +static Weekday WeekdayFromDaysOfWeek(UCalendarDaysOfWeek weekday) { + switch (weekday) { + case UCAL_MONDAY: + return Weekday::Monday; + case UCAL_TUESDAY: + return Weekday::Tuesday; + case UCAL_WEDNESDAY: + return Weekday::Wednesday; + case UCAL_THURSDAY: + return Weekday::Thursday; + case UCAL_FRIDAY: + return Weekday::Friday; + case UCAL_SATURDAY: + return Weekday::Saturday; + case UCAL_SUNDAY: + return Weekday::Sunday; + } + MOZ_CRASH("unexpected weekday value"); +} + +Result, ICUError> Calendar::GetWeekend() { + static_assert(static_cast(UCAL_SUNDAY) == 1); + static_assert(static_cast(UCAL_SATURDAY) == 7); + + UErrorCode status = U_ZERO_ERROR; + + EnumSet weekend; + for (int32_t i = UCAL_SUNDAY; i <= UCAL_SATURDAY; i++) { + auto dayOfWeek = static_cast(i); + auto type = ucal_getDayOfWeekType(mCalendar, dayOfWeek, &status); + if (U_FAILURE(status)) { + return Err(ToICUError(status)); + } + + switch (type) { + case UCAL_WEEKEND_ONSET: + // Treat days which start as a weekday as weekdays. + [[fallthrough]]; + case UCAL_WEEKDAY: + break; + + case UCAL_WEEKEND_CEASE: + // Treat days which start as a weekend day as weekend days. + [[fallthrough]]; + case UCAL_WEEKEND: + weekend += WeekdayFromDaysOfWeek(dayOfWeek); + break; + } + } + + return weekend; +} + +Weekday Calendar::GetFirstDayOfWeek() { + int32_t firstDayOfWeek = ucal_getAttribute(mCalendar, UCAL_FIRST_DAY_OF_WEEK); + MOZ_ASSERT(UCAL_SUNDAY <= firstDayOfWeek && firstDayOfWeek <= UCAL_SATURDAY); + + return WeekdayFromDaysOfWeek( + static_cast(firstDayOfWeek)); +} + +int32_t Calendar::GetMinimalDaysInFirstWeek() { + int32_t minimalDays = + ucal_getAttribute(mCalendar, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK); + MOZ_ASSERT(1 <= minimalDays && minimalDays <= 7); + + return minimalDays; +} + +Result Calendar::SetTimeInMs(double aUnixEpoch) { + UErrorCode status = U_ZERO_ERROR; + ucal_setMillis(mCalendar, aUnixEpoch, &status); + if (U_FAILURE(status)) { + return Err(ToICUError(status)); + } + return Ok{}; +} + +/* static */ +Result, ICUError> +Calendar::GetLegacyKeywordValuesForLocale(const char* aLocale) { + UErrorCode status = U_ZERO_ERROR; + UEnumeration* enumeration = ucal_getKeywordValuesForLocale( + "calendar", aLocale, /* commonlyUsed */ false, &status); + + if (U_SUCCESS(status)) { + return SpanEnumeration(enumeration); + } + + return Err(ToICUError(status)); +} + +/* static */ +SpanResult Calendar::LegacyIdentifierToBcp47(const char* aIdentifier, + int32_t aLength) { + if (aIdentifier == nullptr) { + return Err(InternalError{}); + } + // aLength is not needed here, as the ICU call uses the null terminated + // string. + return MakeStringSpan(uloc_toUnicodeLocaleType("ca", aIdentifier)); +} + +/* static */ +Result +Calendar::GetBcp47KeywordValuesForLocale(const char* aLocale, + CommonlyUsed aCommonlyUsed) { + UErrorCode status = U_ZERO_ERROR; + UEnumeration* enumeration = ucal_getKeywordValuesForLocale( + "calendar", aLocale, static_cast(aCommonlyUsed), &status); + + if (U_SUCCESS(status)) { + return Bcp47IdentifierEnumeration(enumeration); + } + + return Err(ToICUError(status)); +} + +Calendar::~Calendar() { + MOZ_ASSERT(mCalendar); + ucal_close(mCalendar); +} + +} // namespace mozilla::intl -- cgit v1.2.3