diff options
author | gennyble <gen@nyble.dev> | 2024-04-13 05:40:17 -0500 |
---|---|---|
committer | gennyble <gen@nyble.dev> | 2024-04-13 05:40:17 -0500 |
commit | fafb3c3ceaa16e93f69b38e33e64e240573e4875 (patch) | |
tree | c49c9eb94e6c14c089847c02ba156d5566e5b118 /src/ifc.rs | |
parent | 1b93aecbdc261ca2f7932db2754c6e33487dd9c8 (diff) | |
download | awake-fafb3c3ceaa16e93f69b38e33e64e240573e4875.tar.gz awake-fafb3c3ceaa16e93f69b38e33e64e240573e4875.zip |
:)
Diffstat (limited to 'src/ifc.rs')
-rw-r--r-- | src/ifc.rs | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/ifc.rs b/src/ifc.rs new file mode 100644 index 0000000..d0a9f5f --- /dev/null +++ b/src/ifc.rs @@ -0,0 +1,112 @@ +//! The international fixed calendar is a 13-month calendar with each month +//! containing exactly 28 days. There is an extra day at the end of the year +//! called the year day. +//! +//! In leap-years there is an extra day inserted at the end of June called the +//! leap day. It is directly after the fourth week of june and is given to june, +//! so it becomes June 29th. The day after June 29th starts the new month, Sol, +//! with Sol 1. +//! +//! [Wikipedia: International Fixed Calendar][wp-ifc] +//! [wp-ifc]: https://en.wikipedia.org/wiki/International_Fixed_Calendar + +use time::Date as TimeDate; + +const MONTHS: [[&str; 2]; 13] = [ + ["January", "Jan"], + ["February", "Feb"], + ["March", "Mar"], + ["April", "Apr"], + ["May", "May"], + ["June", "Jun"], + ["Sol", "Sol"], + ["July", "Jul"], + ["August", "Aug"], + ["September", "Sep"], + ["October", "Oct"], + ["November", "Nov"], + ["December", "Dec"], +]; + +pub struct Calendar { + pub year: usize, + pub ordinal: usize, +} + +impl Calendar { + pub fn from_year(year: usize) -> Self { + Self { year, ordinal: 0 } + } + + pub fn from_time_date(date: TimeDate) -> Self { + let year = date.year() as usize; + let ord = date.ordinal() as usize; + + Self { year, ordinal: ord } + } +} + +pub struct Date { + pub year: u32, + pub month: u8, + pub day: u8, +} + +impl Date { + pub fn from_time_date(date: TimeDate) -> Self { + let year = date.year() as u32; + let ord = date.ordinal(); + + if !year_leaps(year) || ord <= 168 { + // not a leap year path + // also the "leap year but before the leap-day" path + Self { + year, + month: (ord / 28) as u8, + day: (ord % 28) as u8, + } + } else if ord == 169 { + Self { + year, + month: 6, + day: 29, + } + } else { + todo!() + } + } + + pub fn is_leap(&self) -> bool { + year_leaps(self.year) + } +} + +/// Whether or not a year is a leap year +fn year_leaps(year: u32) -> bool { + let four = year % 4 == 0; + let hundreds = year % 100 == 0; + let fourhund = year % 400 == 0; + + // leap if: + // - four AND NOT hundred + // - four AND hundred AND fourhund + + // `fourhund` here checks `hundreds` by virtue of 100 being a multiple of 400 + four && (!hundreds || fourhund) +} + +mod test { + use crate::ifc::year_leaps; + + #[test] + fn leap_years() { + // the examples given by wikipedia + assert!(year_leaps(2000)); + assert!(!year_leaps(1700)); + assert!(!year_leaps(1800)); + assert!(!year_leaps(1900)); + + // testing the four rule + assert!(year_leaps(2024)); + } +} |