Skip to content

Implement the remaining non-ISO calendar method calls #209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 23, 2025
Merged
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
62 changes: 26 additions & 36 deletions src/builtins/core/calendar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@
//! The goal of the calendar module of `boa_temporal` is to provide
//! Temporal compatible calendar implementations.

// TODO: It may finally be time to clean up API to use `IsoDate` and `DateDuration` directly.

use alloc::string::String;
use alloc::vec::Vec;
use core::str::FromStr;
use icu_calendar::types::{Era as IcuEra, MonthCode as IcuMonthCode, MonthInfo, YearInfo};
use types::ResolveType;

use crate::{
builtins::core::{
duration::{DateDuration, TimeDuration},
Expand All @@ -21,7 +13,9 @@ use crate::{
parsers::parse_allowed_calendar_formats,
TemporalError, TemporalResult,
};
use core::str::FromStr;

use icu_calendar::types::{Era as IcuEra, MonthCode as IcuMonthCode, MonthInfo, YearInfo};
use icu_calendar::{
any_calendar::AnyDateInner,
cal::{
Expand All @@ -41,8 +35,8 @@ use super::{PartialDate, ZonedDateTime};
mod era;
mod types;

pub use types::ResolvedCalendarFields;
pub(crate) use types::{ascii_four_to_integer, month_to_month_code};
pub use types::{ResolveType, ResolvedCalendarFields};

use era::EraInfo;

Expand Down Expand Up @@ -364,7 +358,6 @@ impl Calendar {
let date_duration = one.diff_iso_date(two, largest_unit)?;
return Ok(Duration::from(date_duration));
}

Err(TemporalError::range().with_message("Not yet implemented."))
}

Expand Down Expand Up @@ -400,56 +393,56 @@ impl Calendar {
if self.is_iso() {
return Ok(iso_date.month);
}

Err(TemporalError::range().with_message("Not yet implemented."))
let calendar_date = self.0.date_from_iso(iso_date.as_icu4x()?);
Ok(self.0.month(&calendar_date).month_number())
}

/// `CalendarMonthCode`
pub fn month_code(&self, iso_date: &IsoDate) -> TemporalResult<TinyAsciiStr<4>> {
if self.is_iso() {
return Ok(iso_date.as_icu4x()?.month().standard_code.0);
}

Err(TemporalError::range().with_message("Not yet implemented."))
let calendar_date = self.0.date_from_iso(iso_date.as_icu4x()?);
Ok(self.0.month(&calendar_date).standard_code.0)
}

/// `CalendarDay`
pub fn day(&self, iso_date: &IsoDate) -> TemporalResult<u8> {
if self.is_iso() {
return Ok(iso_date.day);
}

Err(TemporalError::range().with_message("Not yet implemented."))
let calendar_date = self.0.date_from_iso(iso_date.as_icu4x()?);
Ok(self.0.day_of_month(&calendar_date).0)
}

/// `CalendarDayOfWeek`
pub fn day_of_week(&self, iso_date: &IsoDate) -> TemporalResult<u16> {
if self.is_iso() {
return Ok(iso_date.as_icu4x()?.day_of_week() as u16);
}

Err(TemporalError::range().with_message("Not yet implemented."))
let calendar_date = self.0.date_from_iso(iso_date.as_icu4x()?);
// TODO: Understand ICU4X's decision for `IsoWeekDay` to be `i8`
Ok(self.0.day_of_week(&calendar_date) as u16)
}

/// `CalendarDayOfYear`
pub fn day_of_year(&self, iso_date: &IsoDate) -> TemporalResult<u16> {
if self.is_iso() {
return Ok(iso_date.as_icu4x()?.day_of_year_info().day_of_year);
}
Err(TemporalError::range().with_message("Not yet implemented."))?
let calendar_date = self.0.date_from_iso(iso_date.as_icu4x()?);
Ok(self.0.day_of_year_info(&calendar_date).day_of_year)
}

/// `CalendarWeekOfYear`
pub fn week_of_year(&self, iso_date: &IsoDate) -> TemporalResult<Option<u16>> {
if self.is_iso() {
let date = iso_date.as_icu4x()?;

let week_calculator = WeekCalculator::default();

let week_of = date.week_of_year(&week_calculator);

return Ok(Some(week_of.week as u16));
}
// TODO: Research in ICU4X and determine best approach.
Err(TemporalError::range().with_message("Not yet implemented."))
}

Expand All @@ -468,6 +461,7 @@ impl Calendar {
RelativeUnit::Next => Ok(Some(date.year().extended_year + 1)),
};
}
// TODO: Research in ICU4X and determine best approach.
Err(TemporalError::range().with_message("Not yet implemented."))
}

Expand All @@ -476,6 +470,7 @@ impl Calendar {
if self.is_iso() {
return Ok(7);
}
// TODO: Research in ICU4X and determine best approach.
Err(TemporalError::range().with_message("Not yet implemented."))
}

Expand All @@ -484,40 +479,35 @@ impl Calendar {
if self.is_iso() {
return Ok(iso_date.as_icu4x()?.days_in_month() as u16);
}
Err(TemporalError::range().with_message("Not yet implemented."))
let calendar_date = self.0.date_from_iso(iso_date.as_icu4x()?);
Ok(self.0.days_in_month(&calendar_date) as u16)
}

/// `CalendarDaysInYear`
pub fn days_in_year(&self, iso_date: &IsoDate) -> TemporalResult<u16> {
if self.is_iso() {
return Ok(iso_date.as_icu4x()?.days_in_year());
}

Err(TemporalError::range().with_message("Not yet implemented."))
let calendar_date = self.0.date_from_iso(iso_date.as_icu4x()?);
Ok(self.0.days_in_year(&calendar_date))
}

/// `CalendarMonthsInYear`
pub fn months_in_year(&self, _iso_date: &IsoDate) -> TemporalResult<u16> {
pub fn months_in_year(&self, iso_date: &IsoDate) -> TemporalResult<u16> {
if self.is_iso() {
return Ok(12);
}
Err(TemporalError::range().with_message("Not yet implemented."))
let calendar_date = self.0.date_from_iso(iso_date.as_icu4x()?);
Ok(self.0.months_in_year(&calendar_date) as u16)
}

/// `CalendarInLeapYear`
pub fn in_leap_year(&self, iso_date: &IsoDate) -> TemporalResult<bool> {
if self.is_iso() {
return Ok(iso_date.as_icu4x()?.is_in_leap_year());
}
Err(TemporalError::range().with_message("Not yet implemented."))
}

/// `CalendarFields`
pub fn fields(&self, fields: Vec<String>) -> TemporalResult<Vec<String>> {
if self.is_iso() {
return Ok(fields);
}
Err(TemporalError::range().with_message("Not yet implemented."))
let calendar_date = self.0.date_from_iso(iso_date.as_icu4x()?);
Ok(self.0.is_in_leap_year(&calendar_date))
}

/// Returns the identifier of this calendar slot.
Expand Down