commit be4ddfb1f4e5c2c1cfdc8fec68aee231b2a3bbdc
parent 2939c8cad5f0c48696bcb2b5bf769385e7360639
Author: André Bargull <andre.bargull@gmail.com>
Date: Tue, 2 Dec 2025 08:59:14 +0000
Bug 2002735: Change Coptic calendar implementation to use a single era. r=platform-i18n-reviewers,dminor
CLDR 48 removed the data for the BCE era, which results in outputting an empty
string when the Coptic calendar uses the BCE era. Patch `CopticCalendar` to use
a single era, based on how `EthiopicAmeteAlemCalendar` works.
`CopticCalendar::EEras::BCE` must not be removed, because the era `enum` also
works as the index into the CLDR data, which starts at index 1 for the Coptic
calendar era data (index 0 is unused).
Differential Revision: https://phabricator.services.mozilla.com/D274261
Diffstat:
4 files changed, 127 insertions(+), 19 deletions(-)
diff --git a/intl/icu-patches/bug-2002735-ICU-23277-coptic-single-era.diff b/intl/icu-patches/bug-2002735-ICU-23277-coptic-single-era.diff
@@ -0,0 +1,109 @@
+diff --git a/intl/icu/source/i18n/coptccal.cpp b/intl/icu/source/i18n/coptccal.cpp
+--- a/intl/icu/source/i18n/coptccal.cpp
++++ b/intl/icu/source/i18n/coptccal.cpp
+@@ -61,46 +61,43 @@ int32_t
+ CopticCalendar::handleGetExtendedYear(UErrorCode& status)
+ {
+ if (U_FAILURE(status)) {
+ return 0;
+ }
+ if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) {
+ return internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1
+ }
+- // The year defaults to the epoch start, the era to CE
+- int32_t era = internalGet(UCAL_ERA, CE);
+- if (era == BCE) {
+- return 1 - internalGet(UCAL_YEAR, 1); // Convert to extended year
+- }
+- if (era == CE){
+- return internalGet(UCAL_YEAR, 1); // Default to year 1
+- }
+- status = U_ILLEGAL_ARGUMENT_ERROR;
+- return 0;
++ // The year defaults to the epoch start
++ return internalGet(UCAL_YEAR, 1); // Default to year 1
+ }
+
+ IMPL_SYSTEM_DEFAULT_CENTURY(CopticCalendar, "@calendar=coptic")
+
+ int32_t
+ CopticCalendar::getJDEpochOffset() const
+ {
+ return COPTIC_JD_EPOCH_OFFSET;
+ }
+
+ int32_t CopticCalendar::extendedYearToEra(int32_t extendedYear) const {
+- return extendedYear <= 0 ? BCE : CE;
++ return CE;
+ }
+
+ int32_t CopticCalendar::extendedYearToYear(int32_t extendedYear) const {
+- return extendedYear <= 0 ? 1 - extendedYear : extendedYear;
++ return extendedYear;
+ }
+
+-bool CopticCalendar::isEra0CountingBackward() const {
+- return true;
++int32_t
++CopticCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const
++{
++ if (field == UCAL_ERA) {
++ return 1; // Only one era, era is always 1
++ }
++ return CECalendar::handleGetLimit(field, limitType);
+ }
+
+ int32_t
+ CopticCalendar::getRelatedYearDifference() const {
+ constexpr int32_t kCopticCalendarRelatedYearDifference = 284;
+ return kCopticCalendarRelatedYearDifference;
+ }
+
+diff --git a/intl/icu/source/i18n/coptccal.h b/intl/icu/source/i18n/coptccal.h
+--- a/intl/icu/source/i18n/coptccal.h
++++ b/intl/icu/source/i18n/coptccal.h
+@@ -165,16 +165,22 @@ protected:
+ int32_t getRelatedYearDifference() const override;
+
+ /**
+ * Return the extended year defined by the current fields.
+ * @internal
+ */
+ virtual int32_t handleGetExtendedYear(UErrorCode& status) override;
+
++ /**
++ * Calculate the limit for a specified type of limit and field
++ * @internal
++ */
++ virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const override;
++
+ DECLARE_OVERRIDE_SYSTEM_DEFAULT_CENTURY
+
+ /**
+ * Return the date offset from Julian
+ * @internal
+ */
+ int32_t getJDEpochOffset() const override;
+
+@@ -184,21 +190,16 @@ protected:
+ */
+ int32_t extendedYearToEra(int32_t extendedYear) const override;
+
+ /**
+ * Compute the year from extended year.
+ * @internal
+ */
+ int32_t extendedYearToYear(int32_t extendedYear) const override;
+-
+- /**
+- * @internal
+- */
+- bool isEra0CountingBackward() const override;
+ public:
+ /**
+ * Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
+ * override. This method is to implement a simple version of RTTI, since not all C++
+ * compilers support genuine RTTI. Polymorphic operator==() and clone() methods call
+ * this method.
+ *
+ * @return The class ID for this object. All objects of a given class have the
diff --git a/intl/icu/source/i18n/coptccal.cpp b/intl/icu/source/i18n/coptccal.cpp
@@ -66,16 +66,8 @@ CopticCalendar::handleGetExtendedYear(UErrorCode& status)
if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) {
return internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1
}
- // The year defaults to the epoch start, the era to CE
- int32_t era = internalGet(UCAL_ERA, CE);
- if (era == BCE) {
- return 1 - internalGet(UCAL_YEAR, 1); // Convert to extended year
- }
- if (era == CE){
- return internalGet(UCAL_YEAR, 1); // Default to year 1
- }
- status = U_ILLEGAL_ARGUMENT_ERROR;
- return 0;
+ // The year defaults to the epoch start
+ return internalGet(UCAL_YEAR, 1); // Default to year 1
}
IMPL_SYSTEM_DEFAULT_CENTURY(CopticCalendar, "@calendar=coptic")
@@ -87,15 +79,20 @@ CopticCalendar::getJDEpochOffset() const
}
int32_t CopticCalendar::extendedYearToEra(int32_t extendedYear) const {
- return extendedYear <= 0 ? BCE : CE;
+ return CE;
}
int32_t CopticCalendar::extendedYearToYear(int32_t extendedYear) const {
- return extendedYear <= 0 ? 1 - extendedYear : extendedYear;
+ return extendedYear;
}
-bool CopticCalendar::isEra0CountingBackward() const {
- return true;
+int32_t
+CopticCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const
+{
+ if (field == UCAL_ERA) {
+ return 1; // Only one era, era is always 1
+ }
+ return CECalendar::handleGetLimit(field, limitType);
}
int32_t
diff --git a/intl/icu/source/i18n/coptccal.h b/intl/icu/source/i18n/coptccal.h
@@ -170,6 +170,12 @@ protected:
*/
virtual int32_t handleGetExtendedYear(UErrorCode& status) override;
+ /**
+ * Calculate the limit for a specified type of limit and field
+ * @internal
+ */
+ virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const override;
+
DECLARE_OVERRIDE_SYSTEM_DEFAULT_CENTURY
/**
@@ -189,11 +195,6 @@ protected:
* @internal
*/
int32_t extendedYearToYear(int32_t extendedYear) const override;
-
- /**
- * @internal
- */
- bool isEra0CountingBackward() const override;
public:
/**
* Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
diff --git a/intl/update-icu.sh b/intl/update-icu.sh
@@ -64,6 +64,7 @@ for patch in \
bug-1972781-chinese-based-calendar.diff \
bug-2000225-ICU-23264-increase-measure-unit-capacity.diff \
bug-2000225-ICU-23262-missing-resource-error-for-iso8601-era.diff \
+ bug-2002735-ICU-23277-coptic-single-era.diff \
bug-2002997-ICU-23278-metazone-with-offset.diff \
; do
echo "Applying local patch $patch"