Skip to content

Commit f67645a

Browse files
Unify day-of-week calculation (#6368)
Weekdays are not calender-specific, and the current code is overly complex.
1 parent 17517bb commit f67645a

File tree

13 files changed

+54
-113
lines changed

13 files changed

+54
-113
lines changed

components/calendar/src/cal/coptic.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,6 @@ impl Calendar for Coptic {
131131
date.0.days_in_month()
132132
}
133133

134-
fn day_of_week(&self, date: &Self::DateInner) -> types::Weekday {
135-
Iso.day_of_week(Coptic.date_to_iso(date).inner())
136-
}
137-
138134
fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) {
139135
date.0.offset_date(offset, &());
140136
}

components/calendar/src/cal/dangi.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,6 @@ impl Calendar for Dangi {
242242
date.0 .0.day_of_year()
243243
}
244244

245-
fn day_of_week(&self, date: &Self::DateInner) -> crate::types::Weekday {
246-
self.date_to_iso(date).day_of_week()
247-
}
248-
249245
fn any_calendar_kind(&self) -> Option<crate::AnyCalendarKind> {
250246
Some(crate::any_calendar::IntoAnyCalendar::kind(self))
251247
}

components/calendar/src/cal/ethiopian.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,6 @@ impl Calendar for Ethiopian {
158158
date.0.days_in_month()
159159
}
160160

161-
fn day_of_week(&self, date: &Self::DateInner) -> types::Weekday {
162-
Iso.day_of_week(self.date_to_iso(date).inner())
163-
}
164-
165161
fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) {
166162
date.0.offset_date(offset, &());
167163
}

components/calendar/src/cal/hebrew.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -497,10 +497,10 @@ mod tests {
497497
let cal = Hebrew::new();
498498
let era = "am";
499499
let month_code = MonthCode(tinystr!(4, "M01"));
500-
let dt = cal.date_from_codes(Some(era), 3760, month_code, 1).unwrap();
500+
let dt = Date::try_new_from_codes(Some(era), 3760, month_code, 1, cal).unwrap();
501501

502502
// Should be Saturday per:
503503
// https://www.hebcal.com/converter?hd=1&hm=Tishrei&hy=3760&h2g=1
504-
assert_eq!(6, cal.day_of_week(&dt) as usize);
504+
assert_eq!(6, dt.day_of_week() as usize);
505505
}
506506
}

components/calendar/src/cal/hijri.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -484,10 +484,6 @@ impl Calendar for HijriObservational {
484484
date.0.days_in_month()
485485
}
486486

487-
fn day_of_week(&self, date: &Self::DateInner) -> types::Weekday {
488-
Iso.day_of_week(self.date_to_iso(date).inner())
489-
}
490-
491487
fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) {
492488
date.0.offset_date(offset, &self.precomputed_data())
493489
}
@@ -839,10 +835,6 @@ impl Calendar for HijriCivil {
839835
date.0.days_in_month()
840836
}
841837

842-
fn day_of_week(&self, date: &Self::DateInner) -> types::Weekday {
843-
Iso.day_of_week(self.date_to_iso(date).inner())
844-
}
845-
846838
fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) {
847839
date.0.offset_date(offset, &())
848840
}
@@ -1020,10 +1012,6 @@ impl Calendar for HijriTabular {
10201012
date.0.days_in_month()
10211013
}
10221014

1023-
fn day_of_week(&self, date: &Self::DateInner) -> types::Weekday {
1024-
Iso.day_of_week(self.date_to_iso(date).inner())
1025-
}
1026-
10271015
fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) {
10281016
date.0.offset_date(offset, &())
10291017
}

components/calendar/src/cal/indian.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,6 @@ impl Calendar for Indian {
156156
date.0.days_in_month()
157157
}
158158

159-
fn day_of_week(&self, date: &Self::DateInner) -> types::Weekday {
160-
Iso.day_of_week(Indian.date_to_iso(date).inner())
161-
}
162-
163159
fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) {
164160
date.0.offset_date(offset, &());
165161
}

components/calendar/src/cal/iso.rs

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -114,54 +114,6 @@ impl Calendar for Iso {
114114
date.0.days_in_month()
115115
}
116116

117-
fn day_of_week(&self, date: &Self::DateInner) -> types::Weekday {
118-
// For the purposes of the calculation here, Monday is 0, Sunday is 6
119-
// ISO has Monday=1, Sunday=7, which we transform in the last step
120-
121-
// The days of the week are the same every 400 years
122-
// so we normalize to the nearest multiple of 400
123-
let years_since_400 = date.0.year.rem_euclid(400);
124-
debug_assert!(years_since_400 >= 0); // rem_euclid returns positive numbers
125-
let years_since_400 = years_since_400 as u32;
126-
let leap_years_since_400 = years_since_400 / 4 - years_since_400 / 100;
127-
// The number of days to the current year
128-
// Can never cause an overflow because years_since_400 has a maximum value of 399.
129-
let days_to_current_year = 365 * years_since_400 + leap_years_since_400;
130-
// The weekday offset from January 1 this year and January 1 2000
131-
let year_offset = days_to_current_year % 7;
132-
133-
// Corresponding months from
134-
// https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week#Corresponding_months
135-
let month_offset = if Self::is_leap_year(date.0.year, ()) {
136-
match date.0.month {
137-
10 => 0,
138-
5 => 1,
139-
2 | 8 => 2,
140-
3 | 11 => 3,
141-
6 => 4,
142-
9 | 12 => 5,
143-
1 | 4 | 7 => 6,
144-
_ => unreachable!(),
145-
}
146-
} else {
147-
match date.0.month {
148-
1 | 10 => 0,
149-
5 => 1,
150-
8 => 2,
151-
2 | 3 | 11 => 3,
152-
6 => 4,
153-
9 | 12 => 5,
154-
4 | 7 => 6,
155-
_ => unreachable!(),
156-
}
157-
};
158-
let january_1_2000 = 5; // Saturday
159-
let day_offset = (january_1_2000 + year_offset + month_offset + date.0.day as u32) % 7;
160-
161-
// We calculated in a zero-indexed fashion, but ISO specifies one-indexed
162-
types::Weekday::from((day_offset + 1) as usize)
163-
}
164-
165117
fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) {
166118
date.0.offset_date(offset, &());
167119
}

components/calendar/src/cal/julian.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,6 @@ impl Calendar for Julian {
122122
date.0.days_in_month()
123123
}
124124

125-
fn day_of_week(&self, date: &Self::DateInner) -> types::Weekday {
126-
Iso.day_of_week(Julian.date_to_iso(date).inner())
127-
}
128-
129125
fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) {
130126
date.0.offset_date(offset, &());
131127
}

components/calendar/src/cal/persian.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,6 @@ impl Calendar for Persian {
123123
date.0.days_in_month()
124124
}
125125

126-
fn day_of_week(&self, date: &Self::DateInner) -> types::Weekday {
127-
Iso.day_of_week(self.date_to_iso(date).inner())
128-
}
129-
130126
fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>) {
131127
date.0.offset_date(offset, &())
132128
}

components/calendar/src/calendar.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,6 @@ pub trait Calendar {
4747
/// Count the number of days in a given month, specified by providing a date
4848
/// from that year/month
4949
fn days_in_month(&self, date: &Self::DateInner) -> u8;
50-
/// Calculate the day of the week and return it
51-
fn day_of_week(&self, date: &Self::DateInner) -> types::Weekday {
52-
self.date_to_iso(date).day_of_week()
53-
}
5450
// fn week_of_year(&self, date: &Self::DateInner) -> u8;
5551

5652
#[doc(hidden)] // unstable

0 commit comments

Comments
 (0)