Skip to content

Cleanup utils module #215

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
15 changes: 11 additions & 4 deletions src/builtins/core/year_month.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! This module implements `YearMonth` and any directly related algorithms.

use alloc::string::String;
use alloc::{format, string::String};
use core::{cmp::Ordering, str::FromStr};

use tinystr::TinyAsciiStr;
@@ -9,7 +9,6 @@ use crate::{
iso::{year_month_within_limits, IsoDate},
options::{ArithmeticOverflow, DifferenceOperation, DifferenceSettings, DisplayCalendar},
parsers::{FormattableCalendar, FormattableDate, FormattableYearMonth},
utils::pad_iso_year,
Calendar, MonthCode, TemporalError, TemporalResult, TemporalUnwrap,
};

@@ -103,11 +102,19 @@ impl PlainYearMonth {
self.iso.year
}

/// Returns the padded ISO year string
/// 3.5.11 PadISOYear ( y )
///
/// Returns a String representation of y suitable for inclusion in an ISO 8601 string.
#[inline]
#[must_use]
pub fn padded_iso_year_string(&self) -> String {
pad_iso_year(self.iso.year)
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 this can actually be removed. We're not using this in Boa and to_ixdtf_string supersedes it. For some reason, I didn't notice this was still part of the public API.

let year = self.iso.year;
if (0..9999).contains(&year) {
return format!("{:04}", year);
}
let year_sign = if year > 0 { "+" } else { "-" };
let year_string = format!("{:06}", year.abs());
format!("{year_sign}{year_string}",)
}

/// Returns the iso month value for this `YearMonth`.
27 changes: 13 additions & 14 deletions src/iso.rs
Original file line number Diff line number Diff line change
@@ -91,7 +91,7 @@ impl IsoDateTime {
// 3. Let epochMilliseconds be 𝔽((epochNanoseconds - remainderNs) / 10^6).
let epoch_millis = (mathematical_nanos - remainder_nanos) / 1_000_000;

let (year, month, day) = utils::ymd_from_epoch_milliseconds(epoch_millis);
let (year, month, day) = utils::Epoch::new(epoch_millis).ymd();

// 7. Let hour be ℝ(! HourFromTime(epochMilliseconds)).
let hour = epoch_millis.div_euclid(3_600_000).rem_euclid(24);
@@ -344,8 +344,7 @@ impl IsoDate {
/// Equivalent to `BalanceISODate`.
pub(crate) fn balance(year: i32, month: i32, day: i32) -> Self {
let epoch_days = iso_date_to_epoch_days(year, month, day);
let ms = utils::epoch_days_to_epoch_ms(epoch_days, 0);
let (year, month, day) = utils::ymd_from_epoch_milliseconds(ms);
let (year, month, day) = utils::Epoch::from_days(epoch_days).ymd();
Self::new_unchecked(year, month, day)
}

@@ -367,7 +366,7 @@ impl IsoDate {
/// Equivalent to `IsoDateToEpochDays`
#[inline]
pub(crate) fn to_epoch_days(self) -> i32 {
utils::epoch_days_from_gregorian_date(self.year, self.month, self.day)
utils::Epoch::from_gregorian_date(self.year, self.month, self.day).days()
}

/// Returns if the current `IsoDate` is valid.
@@ -488,12 +487,13 @@ impl IsoDate {

// NOTE: Below is adapted from the polyfill. Preferring this as it avoids looping.
// 11. Let weeks be 0.
let days = utils::epoch_days_from_gregorian_date(other.year, other.month, other.day)
- utils::epoch_days_from_gregorian_date(
let days = utils::Epoch::from_gregorian_date(other.year, other.month, other.day).days()
- utils::Epoch::from_gregorian_date(
constrained.year,
constrained.month,
constrained.day,
);
)
.days();

let (weeks, days) = if largest_unit == TemporalUnit::Week {
(days / 7, days % 7)
@@ -905,8 +905,7 @@ const MAX_EPOCH_DAYS: i32 = 10i32.pow(8) + 1;
#[inline]
/// Utility function to determine if a `DateTime`'s components create a `DateTime` within valid limits
fn iso_dt_within_valid_limits(date: IsoDate, time: &IsoTime) -> bool {
if utils::epoch_days_from_gregorian_date(date.year, date.month, date.day).abs() > MAX_EPOCH_DAYS
{
if utils::Epoch::from_gregorian_date(date.year, date.month, date.day).days() > MAX_EPOCH_DAYS {
return false;
}

@@ -927,7 +926,7 @@ fn utc_epoch_nanos(date: IsoDate, time: &IsoTime) -> TemporalResult<EpochNanosec
#[inline]
fn to_unchecked_epoch_nanoseconds(date: IsoDate, time: &IsoTime) -> i128 {
let ms = time.to_epoch_ms();
let epoch_ms = utils::epoch_days_to_epoch_ms(date.to_epoch_days(), ms);
let epoch_ms = utils::Epoch::from_days(date.to_epoch_days()).millis() + ms;
epoch_ms as i128 * 1_000_000 + time.microsecond as i128 * 1_000 + time.nanosecond as i128
}

@@ -943,10 +942,10 @@ pub(crate) fn iso_date_to_epoch_days(year: i32, month: i32, day: i32) -> i32 {
let resolved_month = month.rem_euclid(12) as u8;
// 3. Find a time t such that EpochTimeToEpochYear(t) is resolvedYear,
// EpochTimeToMonthInYear(t) is resolvedMonth, and EpochTimeToDate(t) is 1.
let epoch_days = utils::epoch_days_from_gregorian_date(resolved_year, resolved_month, 1);
let epoch_days = utils::Epoch::from_gregorian_date(resolved_year, resolved_month, 1);

// 4. Return EpochTimeToDayNumber(t) + date - 1.
epoch_days + day - 1
epoch_days.days() + day - 1
}

#[inline]
@@ -997,13 +996,13 @@ fn balance_iso_year_month(year: i32, month: i32) -> (i32, u8) {
/// Note: month is 1 based.
#[inline]
pub(crate) fn constrain_iso_day(year: i32, month: u8, day: u8) -> u8 {
let days_in_month = utils::iso_days_in_month(year, month);
let days_in_month = utils::Epoch::from_gregorian_date(year, month, 1).days_in_month();
day.clamp(1, days_in_month)
}

#[inline]
pub(crate) fn is_valid_iso_day(year: i32, month: u8, day: u8) -> bool {
let days_in_month = utils::iso_days_in_month(year, month);
let days_in_month = utils::Epoch::from_gregorian_date(year, month, 1).days_in_month();
(1..=days_in_month).contains(&day)
}

Loading