1 //! This module and its contents are not subject to stability guarantees and
2 //! should not be relied upon.
3 //!
4 //! These methods either exist to reduce duplication in code elsewhere or are
5 //! public only for usage in macros. The reasoning for a method's existence is
6 //! generally documented alongside the method.
7 //!
8 //! Failure to ensure that parameters to the contained functions are in range
9 //! will likely result in invalid behavior.
10
11 #![doc(hidden)]
12 #![allow(missing_debug_implementations, missing_copy_implementations)]
13
14 use crate::{days_in_year, is_leap_year, Weekday};
15 use const_fn::const_fn;
16
17 pub struct Time;
18
19 impl Time {
20 /// Create a `Time` from its components.
from_hms_nanos_unchecked( hour: u8, minute: u8, second: u8, nanosecond: u32, ) -> crate::Time21 pub const fn from_hms_nanos_unchecked(
22 hour: u8,
23 minute: u8,
24 second: u8,
25 nanosecond: u32,
26 ) -> crate::Time {
27 crate::Time {
28 hour,
29 minute,
30 second,
31 nanosecond,
32 }
33 }
34 }
35
36 pub struct Date;
37
38 impl Date {
39 // macros
from_yo_unchecked(year: i32, ordinal: u16) -> crate::Date40 pub const fn from_yo_unchecked(year: i32, ordinal: u16) -> crate::Date {
41 crate::Date {
42 value: (year << 9) | ordinal as i32,
43 }
44 }
45
46 // reduce duplication
from_ymd_unchecked(year: i32, month: u8, day: u8) -> crate::Date47 pub(crate) const fn from_ymd_unchecked(year: i32, month: u8, day: u8) -> crate::Date {
48 /// Cumulative days through the beginning of a month in both common and
49 /// leap years.
50 const DAYS_CUMULATIVE_COMMON_LEAP: [[u16; 12]; 2] = [
51 [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
52 [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335],
53 ];
54
55 Date::from_yo_unchecked(
56 year,
57 DAYS_CUMULATIVE_COMMON_LEAP[is_leap_year(year) as usize][month as usize - 1]
58 + day as u16,
59 )
60 }
61
62 // reduce duplication
63 #[const_fn("1.46")]
from_iso_ywd_unchecked( year: i32, week: u8, weekday: Weekday, ) -> crate::Date64 pub(crate) const fn from_iso_ywd_unchecked(
65 year: i32,
66 week: u8,
67 weekday: Weekday,
68 ) -> crate::Date {
69 let (ordinal, overflow) = (week as u16 * 7 + weekday.iso_weekday_number() as u16)
70 .overflowing_sub(jan_weekday(year, 4) as u16 + 4);
71
72 if overflow || ordinal == 0 {
73 return Self::from_yo_unchecked(year - 1, ordinal.wrapping_add(days_in_year(year - 1)));
74 }
75
76 let days_in_cur_year = days_in_year(year);
77 if ordinal > days_in_cur_year {
78 Self::from_yo_unchecked(year + 1, ordinal - days_in_cur_year)
79 } else {
80 Self::from_yo_unchecked(year, ordinal)
81 }
82 }
83 }
84
85 /// Obtain the ISO weekday number of a day in January.
86 #[const_fn("1.46")]
jan_weekday(year: i32, ordinal: i32) -> u887 pub(crate) const fn jan_weekday(year: i32, ordinal: i32) -> u8 {
88 let adj_year = year - 1;
89 let rem = (ordinal + adj_year + adj_year / 4 - adj_year / 100 + adj_year / 400 + 6) % 7;
90 if rem < 0 {
91 (rem + 7) as u8
92 } else {
93 rem as u8
94 }
95 }
96