Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions components/calendar/src/cal/buddhist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ use tinystr::tinystr;
/// # Month codes
///
/// This calendar supports 12 solar month codes (`"M01" - "M12"`)
///
/// # Precise definition and limits
///
/// This calendar is defined algorithmically as a solar calendar that is identical to the proleptic Gregorian calendar in everything
/// except year numbering. This is the civil calendar used in Thailand from the year 1941 onwards,
/// but the algorithm is extended proleptically before that.
#[allow(clippy::exhaustive_structs)] // this type is stable
pub struct Buddhist;

Expand Down
33 changes: 31 additions & 2 deletions components/calendar/src/cal/chinese.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ mod simple;
///
/// This calendar is currently in a preview state: formatting for this calendar is not
/// going to be perfect.
///
/// # Precise definition and limits
///
/// This calendar generically covers any Chinese-style lunisolar calendar with twelve months, and leap months possible
/// after any month (at most once per year). Individual variants [`China`] and [`Korea`] contain more information.
#[derive(Clone, Debug, Default, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[allow(clippy::exhaustive_structs)] // newtype
pub struct LunarChinese<X>(pub X);
Expand Down Expand Up @@ -138,11 +143,17 @@ pub trait Rules: Clone + core::fmt::Debug + crate::cal::scaffold::UnstableSealed

/// The [`Rules`] used in China.
///
/// This type agrees with the official data published by the
/// # Precise definition and limits
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

putting the whole docs under this heading feels kind of pointless

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? That's all of what the docs are about in this case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could put a "precise defintion" heading at the top of pretty much every doc comment. if it doesn't separate from some other heading it's pointless

///
/// This calendar is the traditional Chinese lunar calendar as used
/// in China as of the publication date of this crate.
/// This takes a best-effort approach future dates as used in the region.
///
/// This calendar agrees with the official data published by the
/// [Purple Mountain Observatory for the years 1900-2025], as well as with
/// the data published by the [Hong Kong Observatory for the years 1901-2100].
///
/// For years since 1912, this uses the [GB/T 33661-2017] rules.
/// For years since 1912, this uses the official [GB/T 33661-2017] rules.
/// As accurate computation is computationally expensive, years until
/// 2100 are precomputed, and after that this type regresses to a simplified
/// calculation. If accuracy beyond 2100 is required, clients
Expand All @@ -155,6 +166,11 @@ pub trait Rules: Clone + core::fmt::Debug + crate::cal::scaffold::UnstableSealed
/// required before 1900, clients can implement their own [`Rules`] type
/// using data such as from the excellent compilation by [Yuk Tung Liu].
///
/// The precise behavior of this calendar may change in the future if:
/// - New ground truth is established by published government sources
/// - We decide to tweak the simplified calculation
/// - We decide to expand or reduce the range where we are handling past dates.
///
/// [Purple Mountain Observatory for the years 1900-2025]: http://www.pmo.cas.cn/xwdt2019/kpdt2019/202203/P020250414456381274062.pdf
/// [Hong Kong Observatory for the years 1901-2100]: https://www.hko.gov.hk/en/gts/time/conversion.htm
/// [GB/T 33661-2017]: China::gb_t_33661_2017
Expand Down Expand Up @@ -279,6 +295,12 @@ impl Rules for China {

/// The [`Rules`] used in [Korea](https://en.wikipedia.org/wiki/Korean_calendar).
///
/// # Precise definition and limits
///
/// This calendar is the traditional Korean lunar calendar as used
/// in Korea as of the publication date of this crate.
/// This takes a best-effort approach future dates as used in the region.
///
/// This type agrees with the official data published by the
/// [Korea Astronomy and Space Science Institute for the years 1900-2050].
///
Expand All @@ -297,11 +319,18 @@ impl Rules for China {
/// their own [`Rules`] type using data such as from the excellent compilation
/// by [Yuk Tung Liu].
///
/// The precise behavior of this calendar may change in the future if:
/// - New ground truth is established by published government sources
/// - We decide to tweak the simplified calculation
/// - We decide to expand/reduce the range where we are handling past dates.
///
/// [Korea Astronomy and Space Science Institute for the years 1900-2050]: https://astro.kasi.re.kr/life/pageView/5
/// [adapted GB/T 33661-2017]: Korea::adapted_gb_t_33661_2017
/// [GB/T 33661-2017]: China::gb_t_33661_2017
/// [Yuk Tung Liu]: https://ytliu0.github.io/ChineseCalendar/table.html
///
/// # Example
///
/// ```rust
/// use icu::calendar::cal::LunarChinese;
/// use icu::calendar::Date;
Expand Down
6 changes: 6 additions & 0 deletions components/calendar/src/cal/coptic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ use tinystr::tinystr;
///
/// This calendar supports 13 solar month codes (`"M01" - "M13"`), with `"M13"` being used for the short epagomenal month
/// at the end of the year.
///
/// # Precise definition and limits
///
/// This calendar is defined algorithmically as a solar calendar that has 13 months, with a leap day in
/// the 13th month every 4 years. It is used by the Coptic Orthodox Church as of the publication date
/// of this crate, and extends proleptically before the time of its introduction.
#[derive(Copy, Clone, Debug, Hash, Default, Eq, PartialEq, PartialOrd, Ord)]
#[allow(clippy::exhaustive_structs)] // this type is stable
pub struct Coptic;
Expand Down
7 changes: 6 additions & 1 deletion components/calendar/src/cal/ethiopian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ pub enum EthiopianEraStyle {
///
/// This calendar supports 13 solar month codes (`"M01" - "M13"`), with `"M13"` being used for the short epagomenal month
/// at the end of the year.
// The bool specifies whether dates should be in the Amete Alem era scheme
///
/// # Precise definition and limits
///
/// This calendar is defined algorithmically as a solar calendar that has 13 months, with a leap day in
/// the 13th month every 4 years. It is used as a civil calendar in Ethiopia as of the publication date
/// of this crate, and extends proleptically before the time of its introduction.
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
pub struct Ethiopian(EthiopianEraStyle);

Expand Down
7 changes: 7 additions & 0 deletions components/calendar/src/cal/gregorian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ impl GregorianYears for CeBce {
/// # Month codes
///
/// This calendar supports 12 solar month codes (`"M01" - "M12"`)
///
/// # Precise definition and limits
///
/// This calendar is defined algorithmically as a solar calendar that has 12 months, with a leap day in the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this repeats things that are already said in either the introductory paragraph or the Historical accuracy section

Copy link
Member Author

@Manishearth Manishearth Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I cleaned thsi up with Chinese but didn't do that elsewhere. I think duplication is somewhat okay in the Gregorian case but I can refer to the past section.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: this definition does not fully define the calendar (it does not specify all month lenghts). I do find it kind of pointless, however, to try to provide a precise definition for this calendar, it's not like there are multiple competing variants floating around. we already link to Wikipedia for a full discussion

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I wasn't quite sure of how precise to do these.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for simple calendars like Gregorian, Coptic, Julian, Ethiopian, it suffices to say that they are proleptic if we don't say that yet

not every calendar needs a "Precise definition and limits" sections if we already have good docs

/// 2nd month every 4 and 400 years (but not every 100 years). As of 2025 it is a widely used civil calendar
/// in most countries, including the UN. The Gregorian calendar was adopted gradually starting in the 1500s,
/// this calendar extends proleptically before that.
#[derive(Copy, Clone, Debug, Default)]
#[allow(clippy::exhaustive_structs)] // this type is stable
pub struct Gregorian;
Expand Down
11 changes: 11 additions & 0 deletions components/calendar/src/cal/hebrew.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ use calendrical_calculations::rata_die::RataDie;
/// [`MonthInfo`] has slightly divergent behavior: because the regular month Adar is formatted
/// as "Adar II" in a leap year, this calendar will produce the special code `"M06L"` in any [`MonthInfo`]
/// objects it creates.
///
/// # Precise definition and limits
///
/// This calendar is defined algorithmically as a lunar calendar with a leap 6th month every
/// 3rd, 6th, 8th, 11th, 14th, 17th, and 19th years (in a 19-year Metonic cycle). It is used as a
/// liturgical calendar in Judaism as of the publication date of this crate.
/// This calendar uses the the "civil new year" variant where Tishrei is the first month of the year.
/// The precise algorithm used has [changed over time], with the modern one being in place
/// since about 776 CE. This calendar extends that algorithm proleptically before that.
///
/// [changed over time]: https://hakirah.org/vol20AjdlerAppendices.pdf
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Default)]
#[allow(clippy::exhaustive_structs)] // unit struct
pub struct Hebrew;
Expand Down
37 changes: 33 additions & 4 deletions components/calendar/src/cal/hijri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ mod ummalqura_data;
///
/// This calendar is a pure lunar calendar with no leap months. It uses month codes
/// `"M01" - "M12"`.
///
/// # Precise definition and limits
///
/// This calendar generically covers any pure lunar calendar used liturgically in Islam,
/// with 12 months each of length 29 or 30, with an epoch intended to mark the Hijrah in 622 CE.
Comment on lines +53 to +54
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I'm fine saying that the epoch is the Hijrah, but I thought we previously said we needn't make that commitment, which is why we added ECMA reference year functions to the hijri::Rules trait.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think from a calendrical definition perspective saying the epoch is Hijrah is probably good.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need that actually, because PackedHijriYearData needs it

///
/// In practice, this calendar can be backed by a precise algorithm, a lookup in official tables,
/// astronomical simulation, or pure observation.
///
/// Further details can be found on individual calendar types.
#[derive(Clone, Debug, Default, Copy)]
#[allow(clippy::exhaustive_structs)] // newtype
pub struct Hijri<S>(pub S);
Expand Down Expand Up @@ -111,6 +121,14 @@ pub trait Rules: Clone + Debug + crate::cal::scaffold::UnstableSealed {
///
/// This corresponds to the `"islamic-rgsa"` [CLDR calendar](https://unicode.org/reports/tr35/#UnicodeCalendarIdentifier)
/// if constructed with [`Hijri::new_simulated_mecca()`].
///
/// # Precise definition and limits
///
/// This calendar simulates the lunar cycle for a given location. This currently
/// simulates the calendar for all time using the same calculations, but we may
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it falls back to tabular when invariants are violated already

/// in the future introduce approximations for non-modern dates.
///
/// The precise behavior of this calendar for any and all dates may change in the future.
#[derive(Copy, Clone, Debug)]
pub struct AstronomicalSimulation {
pub(crate) location: SimulatedLocation,
Expand Down Expand Up @@ -227,15 +245,21 @@ impl Rules for AstronomicalSimulation {

/// [`Hijri`] [`Rules`] for the [Umm al-Qura](https://en.wikipedia.org/wiki/Islamic_calendar#Saudi_Arabia's_Umm_al-Qura_calendar) calendar.
///
/// This corresponds to the `"islamic-umalqura"` [CLDR calendar](https://unicode.org/reports/tr35/#UnicodeCalendarIdentifier).
///
/// # Precise definition and limits
///
/// This calendar represents the Umm al-Qura calendar defined by the Kingdom of Saudi Arabia.
///
/// From the start of 1300 AH (1882-11-12 ISO) to the end of 1600 AH (2174-11-25 ISO), this
/// `Rules` implementation uses Umm al-Qura month lengths obtained from
/// [KACST](https://kacst.gov.sa/). Outside this range, this implementation falls back to
/// [`TabularAlgorithm`] with [`TabularAlgorithmLeapYears::TypeII`] and [`TabularAlgorithmEpoch::Friday`].
///
/// Future versions of this crate may extend the range that uses month length data from the
/// calendar authority.
///
/// This corresponds to the `"islamic-umalqura"` [CLDR calendar](https://unicode.org/reports/tr35/#UnicodeCalendarIdentifier).
/// The precise behavior of this calendar may change in the future if:
/// - New ground truth is established by published government sources
/// - We decide to tweak the simplified calculation
/// - We decide to expand or reduce the range where we are handling past dates.
#[derive(Copy, Clone, Debug, Default)]
#[non_exhaustive]
pub struct UmmAlQura;
Expand Down Expand Up @@ -311,6 +335,11 @@ impl Rules for UmmAlQura {
///
/// When constructed with [`TabularAlgorithmLeapYears::TypeII`], and either [`TabularAlgorithmEpoch::Friday`] or [`TabularAlgorithmEpoch::Thursday`],
/// this corresponds to the `"islamic-civil"` and `"islamic-tbla"` [CLDR calendars](https://unicode.org/reports/tr35/#UnicodeCalendarIdentifier) respectively.
///
/// # Precise definition and limits
///
/// This calendar is defined algorithmically based on the algorithm selected by the choice of [`TabularAlgorithmLeapYears`],
/// and the epoch selected by the choice of [`TabularAlgorithmEpoch`].
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
pub struct TabularAlgorithm {
pub(crate) leap_years: TabularAlgorithmLeapYears,
Expand Down
7 changes: 7 additions & 0 deletions components/calendar/src/cal/indian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ use tinystr::tinystr;
/// # Month codes
///
/// This calendar supports 12 solar month codes (`"M01" - "M12"`)
///
/// # Precise definition and limits
///
/// This calendar is defined algorithmically as a solar calendar that has 12 months, as used alongside the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a very precise definition. month lengths? leap years?

/// Gregorian calendar by the Government of India by the name "Śaka calendar" as of publication date of this crate.
///
/// The Śaka calendar was introduced in 1957, but this calendar extends proleptically before that.
#[derive(Copy, Clone, Debug, Hash, Default, Eq, PartialEq, PartialOrd, Ord)]
#[allow(clippy::exhaustive_structs)] // this type is stable
pub struct Indian;
Expand Down
5 changes: 5 additions & 0 deletions components/calendar/src/cal/iso.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ use tinystr::tinystr;
/// # Month codes
///
/// This calendar supports 12 solar month codes (`"M01" - "M12"`)
///
/// # Precise definition and limits
///
/// This calendar is defined algorithmically as a solar calendar that is identical to the proleptic Gregorian calendar
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the same as the first paragraph

/// in everything except the way eras are handled.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[allow(clippy::exhaustive_structs)] // this type is stable
pub struct Iso;
Expand Down
6 changes: 6 additions & 0 deletions components/calendar/src/cal/japanese.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ use tinystr::tinystr;
/// # Month codes
///
/// This calendar supports 12 solar month codes (`M01` - `M12`)
///
/// # Precise definition and limits
///
/// This calendar is defined algorithmically as a solar calendar that is identical to the proleptic Gregorian calendar in everything
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is already said in the first two paragraphs

/// except year numbering. This is the civil calendar used in Japan from 1873, this calendar extends proleptically
/// before that.
#[derive(Clone, Debug, Default)]
pub struct Japanese {
eras: DataPayload<CalendarJapaneseModernV1>,
Expand Down
6 changes: 6 additions & 0 deletions components/calendar/src/cal/julian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ use tinystr::tinystr;
/// # Month codes
///
/// This calendar supports 12 solar month codes (`"M01" - "M12"`)
///
/// # Precise definition and limits
///
/// This calendar is defined algorithmically as a solar calendar with a leap month every 4 years, as was used
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is already explained in previous paragraphs, and this is not very exact

Copy link
Member Author

@Manishearth Manishearth Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think specifying the year it was used in the Roman empire is quite exact, and the best we can do for a historical calendar. Do you have another suggestion?

/// by the Roman empire in 4 CE. That algorithm is extended proleptically before and after its period of use.
///
#[derive(Copy, Clone, Debug, Hash, Default, Eq, PartialEq, PartialOrd, Ord)]
#[allow(clippy::exhaustive_structs)] // this type is stable
pub struct Julian;
Expand Down
14 changes: 14 additions & 0 deletions components/calendar/src/cal/persian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ use calendrical_calculations::rata_die::RataDie;
/// # Month codes
///
/// This calendar supports 12 solar month codes (`"M01" - "M12"`)
///
/// # Precise definition and limits
///
/// This calendar is defined as a solar calendar which uses the astronomical vernal equinox as its new year, and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how many months? how long?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to be that precise in each calendar? Expressing some characteristics and a polity where it is official is pretty unambiguous.

/// is the official calendar of the Islamic Republic of Iran as of the publication date of this crate. This calendar was introduced in Iran in 1925,
/// but the astronomical calculations are extended proleptically before that.
///
/// As these are pure solar computations, the astronomical calculations can be treated as a relatively
/// precise algorithm and there is much less need to match ground truth. Nevertheless, in the event that the calculations
/// disagree with the ground truth of calendar usage in Iran, the ground truth will prevail.
///
/// The underlying implementation uses a cyclic approximation with overrides to match the precise astronomic calculations
/// for the years 1178-3500 AP. Outside of that range one can expect this calendar implementation to no longer
/// accurately match the astronomical calculations.
#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq, PartialOrd, Ord)]
#[allow(clippy::exhaustive_structs)]
pub struct Persian;
Expand Down
6 changes: 6 additions & 0 deletions components/calendar/src/cal/roc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ use tinystr::tinystr;
/// # Month codes
///
/// This calendar supports 12 solar month codes (`"M01" - "M12"`)
///
/// # Precise definition and limits
///
/// This calendar is defined algorithmically as a solar calendar that is identical to the proleptic Gregorian calendar in everything
/// except year numbering. This is the civil calendar used in the Republic of China from the year 1912 onwards,
/// but the algorithm is extended proleptically before that.
#[derive(Copy, Clone, Debug, Default)]
#[allow(clippy::exhaustive_structs)] // this type is stable
pub struct Roc;
Expand Down