diff --git a/src/components/calendar.rs b/src/components/calendar.rs index 8091557a..aa4ab29c 100644 --- a/src/components/calendar.rs +++ b/src/components/calendar.rs @@ -8,6 +8,7 @@ use alloc::string::{String, ToString}; use alloc::vec::Vec; use core::str::FromStr; +use crate::parsers::parse_date_time; use crate::{ components::{ duration::{DateDuration, TimeDuration}, @@ -190,13 +191,21 @@ impl Calendar { impl FromStr for Calendar { type Err = TemporalError; + // 13.39 ParseTemporalCalendarString ( string ) fn from_str(s: &str) -> Result { + let mut cal_str = s; + if let Ok(record) = parse_date_time(s) { + if let Some(calendar) = record.calendar { + cal_str = calendar; + } + } + // NOTE(nekesss): Catch the iso identifier here, as `iso8601` is not a valid ID below. - if s == "iso8601" { + if cal_str.to_lowercase() == "iso8601" { return Ok(Self::default()); } - let Some(cal) = AnyCalendarKind::get_for_bcp47_string(s) else { + let Some(cal) = AnyCalendarKind::get_for_bcp47_string(cal_str) else { return Err(TemporalError::range().with_message("Not a builtin calendar.")); }; @@ -322,6 +331,7 @@ impl Calendar { resolved_fields.day, self.clone(), overflow, + None, ); } diff --git a/src/components/month_day.rs b/src/components/month_day.rs index 31b7ead8..bca98791 100644 --- a/src/components/month_day.rs +++ b/src/components/month_day.rs @@ -36,9 +36,11 @@ impl PlainMonthDay { day: i32, calendar: Calendar, overflow: ArithmeticOverflow, + ref_year: Option, ) -> TemporalResult { + let ry = ref_year.unwrap_or(1972); // 1972 is the first leap year in the Unix epoch (needed to cover all dates) - let iso = IsoDate::new_with_overflow(1972, month, day, overflow)?; + let iso = IsoDate::new_with_overflow(ry, month, day, overflow)?; Ok(Self::new_unchecked(iso, calendar)) } @@ -56,6 +58,13 @@ impl PlainMonthDay { self.iso.month } + // returns the iso year value of `MonthDay`. + #[inline] + #[must_use] + pub fn iso_year(&self) -> i32 { + self.iso.year + } + /// Returns the string identifier for the current calendar used. #[inline] #[must_use] @@ -108,6 +117,7 @@ impl FromStr for PlainMonthDay { date.day.into(), Calendar::from_str(calendar)?, ArithmeticOverflow::Reject, + None, ) } } diff --git a/src/parsers.rs b/src/parsers.rs index e2096cc4..a4e5f122 100644 --- a/src/parsers.rs +++ b/src/parsers.rs @@ -127,18 +127,8 @@ pub(crate) fn parse_year_month(source: &str) -> TemporalResult #[inline] pub(crate) fn parse_month_day(source: &str) -> TemporalResult { let md_record = parse_ixdtf(source, ParseVariant::MonthDay); - - if let Ok(md) = md_record { - return Ok(md); - } - - let dt_parse = parse_ixdtf(source, ParseVariant::DateTime); - - match dt_parse { - Ok(dt) => Ok(dt), - // Format and return the error from parsing YearMonth. - _ => md_record.map_err(|e| TemporalError::range().with_message(format!("{e}"))), - } + // Error needs to be a RangeError + md_record.map_err(|e| TemporalError::range().with_message(format!("{e}"))) } #[inline]