Skip to content

Commit 2a04310

Browse files
committed
Fill in resolve_day for non-ISO
1 parent 6780fdb commit 2a04310

3 files changed

Lines changed: 82 additions & 6 deletions

File tree

src/builtins/core/calendar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ impl Calendar {
282282
PlainYearMonth::new_with_overflow(
283283
Iso.year_info(&iso).year,
284284
Iso.month(&iso).ordinal,
285-
Some(Iso.days_in_month(&iso)),
285+
Some(Iso.day_of_month(&iso).0),
286286
self.clone(),
287287
overflow,
288288
)

src/builtins/core/calendar/types.rs

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use alloc::format;
88
use crate::iso::{constrain_iso_day, is_valid_iso_day};
99
use crate::options::ArithmeticOverflow;
1010
use crate::{TemporalError, TemporalResult};
11+
use icu_calendar::AnyCalendarKind;
1112

1213
use crate::builtins::core::{calendar::Calendar, PartialDate};
1314

@@ -37,7 +38,13 @@ impl ResolvedCalendarFields {
3738
let era_year = EraYear::try_from_partial_date(partial_date, resolve_type)?;
3839
if partial_date.calendar.is_iso() {
3940
let month_code = resolve_iso_month(partial_date, overflow)?;
40-
let day = resolve_day(partial_date.day, resolve_type == ResolutionType::YearMonth)?;
41+
let day = resolve_day(
42+
partial_date.day,
43+
resolve_type == ResolutionType::YearMonth,
44+
&era_year,
45+
month_code,
46+
&partial_date.calendar,
47+
)?;
4148
let day = if overflow == ArithmeticOverflow::Constrain {
4249
constrain_iso_day(era_year.year, month_code.to_month_integer(), day)
4350
} else {
@@ -56,8 +63,13 @@ impl ResolvedCalendarFields {
5663
}
5764

5865
let month_code = MonthCode::try_from_partial_date(partial_date)?;
59-
let day = resolve_day(partial_date.day, resolve_type == ResolutionType::YearMonth)?;
60-
// TODO: Constrain day to calendar range for month?
66+
let day = resolve_day(
67+
partial_date.day,
68+
resolve_type == ResolutionType::YearMonth,
69+
&era_year,
70+
month_code,
71+
&partial_date.calendar,
72+
)?;
6173

6274
Ok(Self {
6375
era_year,
@@ -67,9 +79,35 @@ impl ResolvedCalendarFields {
6779
}
6880
}
6981

70-
fn resolve_day(day: Option<u8>, is_year_month: bool) -> TemporalResult<u8> {
82+
fn resolve_day(
83+
day: Option<u8>,
84+
is_year_month: bool,
85+
year: &EraYear,
86+
month_code: MonthCode,
87+
calendar: &Calendar,
88+
) -> TemporalResult<u8> {
7189
if is_year_month {
72-
Ok(day.unwrap_or(1))
90+
if calendar.kind() == AnyCalendarKind::Japanese {
91+
Ok(
92+
match (year.arithmetic_year, month_code.to_month_integer()) {
93+
// Meiji begins Oct 23, 1868
94+
(1868, 10) => 23,
95+
// Taisho begins Jul 30, 1912
96+
(1912, 7) => 30,
97+
// Showa begins Dec 12, 1926
98+
(1926, 12) => 25,
99+
// Heisei begins 8 Jan 1989
100+
(1989, 1) => 8,
101+
// Reiwa begins 1 May 2019
102+
(2019, 5) => 1,
103+
_ => 1,
104+
},
105+
)
106+
} else {
107+
// PlainYearMonth construction paths all *require* setting the day to the first day of the month.
108+
// See https://tc39.es/proposal-temporal/#sec-temporal-calendaryearmonthfromfields
109+
Ok(1)
110+
}
73111
} else {
74112
day.ok_or(TemporalError::r#type().with_message("Required day field is empty."))
75113
}

src/builtins/core/year_month.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,4 +1232,42 @@ mod tests {
12321232
assert!(min.since(&max, Default::default()).is_err());
12331233
assert!(min.since(&epoch, Default::default()).is_err());
12341234
}
1235+
1236+
#[test]
1237+
fn test_reference_day() {
1238+
assert_eq!(
1239+
PlainYearMonth::from_str("1868-10-30[u-ca=japanese]")
1240+
.unwrap()
1241+
.reference_day(),
1242+
23
1243+
);
1244+
// Still happens for dates that are in the previous era but same month
1245+
assert_eq!(
1246+
PlainYearMonth::from_str("1868-10-20[u-ca=japanese]")
1247+
.unwrap()
1248+
.reference_day(),
1249+
23
1250+
);
1251+
// Won't happen for dates in other months
1252+
assert_eq!(
1253+
PlainYearMonth::from_str("1868-09-30[u-ca=japanese]")
1254+
.unwrap()
1255+
.reference_day(),
1256+
1
1257+
);
1258+
1259+
// Always 1 in other calendars
1260+
assert_eq!(
1261+
PlainYearMonth::from_str("2000-09-30[u-ca=chinese]")
1262+
.unwrap()
1263+
.reference_day(),
1264+
1
1265+
);
1266+
assert_eq!(
1267+
PlainYearMonth::from_str("2000-09-30[u-ca=hebrew]")
1268+
.unwrap()
1269+
.reference_day(),
1270+
1
1271+
);
1272+
}
12351273
}

0 commit comments

Comments
 (0)