Skip to main content

deep_time/time_parts/
mod.rs

1mod from_bin_ccsds;
2mod from_str;
3mod from_str_ccsds;
4mod to_bin_ccsds;
5mod to_deep_time;
6
7#[cfg(feature = "alloc")]
8mod to_str_ccsds;
9
10#[cfg(feature = "chrono")]
11mod to_chrono;
12
13#[cfg(feature = "jiff")]
14mod to_jiff;
15
16use crate::{LiteStr, Scale};
17
18/// A flexible, partially-filled representation of a civil datetime.
19///
20/// [`TimeParts`] is the central intermediate type used throughout the library
21/// for parsing, formatting, and converting between different time representations
22/// (CCSDS, ISO-like strings, `chrono`, `jiff`, `Dt`, etc.).
23///
24/// Most fields are optional, allowing partial dates/times. It also carries
25/// metadata such as the time `scale`, IANA zone name, leap-second flag,
26/// and various weekday/week-number representations.
27///
28/// - Convert to [`Dt`] using [`TimeParts::to_dt`].
29/// - Conversions to types from other crates require relevant features to
30///   be enabled.
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32#[cfg_attr(feature = "js", derive(tsify::Tsify))]
33#[derive(Debug, Clone, Copy, Default, PartialEq)]
34pub struct TimeParts {
35    /// Year (can be negative for BCE dates).
36    pub yr: Option<i64>,
37    /// Month of the year (1–12).
38    pub mo: Option<u8>,
39    /// Day of the month (1–31).
40    pub day: Option<u8>,
41    /// Hour of the day (0–23).
42    pub hr: u8,
43    /// Minute of the hour (0–59).
44    pub min: u8,
45    /// Second of the minute (0–60). Value 60 is used for leap seconds.
46    pub sec: u8,
47    /// Attoseconds (0 ≤ value < 10¹⁸).
48    pub attos: u64,
49    /// Timezone offset from UTC.
50    pub offset: Option<Offset>,
51    /// IANA timezone name (e.g. `"America/New_York"`), stored as ASCII.
52    pub iana_name: Option<LiteStr<49>>,
53    /// The time scale this value belongs to (TAI, UTC, etc.).
54    pub scale: Scale,
55    /// Day of the week.
56    pub wkday: Option<Weekday>,
57    /// Day of the year (1–366), corresponding to `%j`.
58    pub day_of_yr: Option<u16>,
59    /// ISO week year (`%G` / `%g`).
60    pub iso_wk_yr: Option<i64>,
61    /// ISO week number (1–53), corresponding to `%V`.
62    pub iso_wk: Option<u8>,
63    /// Week number with Sunday as first day of week (0–53), `%U`.
64    pub wk_sun: Option<u8>,
65    /// Week number with Monday as first day of week (0–53), `%W`.
66    pub wk_mon: Option<u8>,
67    /// AM / PM indicator.
68    pub meridiem: Option<Meridiem>,
69    /// Unix timestamp in seconds (`%s`).
70    pub unix_timestamp_seconds: Option<i64>,
71}
72
73impl TimeParts {
74    #[inline(always)]
75    pub fn new_utc() -> TimeParts {
76        Self {
77            scale: Scale::UTC,
78            ..Default::default()
79        }
80    }
81
82    /// Sets the IANA timezone name.
83    #[inline(always)]
84    pub fn set_iana_name(&mut self, name: Option<&str>) {
85        self.iana_name = name.map(LiteStr::new);
86    }
87}
88
89/// AM / PM indicator.
90#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
91#[cfg_attr(feature = "js", derive(tsify::Tsify))]
92#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
93pub enum Meridiem {
94    #[default]
95    AM,
96    PM,
97}
98
99/// Day of the week. Default is set to Sunday.
100#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
101#[cfg_attr(feature = "js", derive(tsify::Tsify))]
102#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
103pub enum Weekday {
104    #[default]
105    Sunday,
106    Monday,
107    Tuesday,
108    Wednesday,
109    Thursday,
110    Friday,
111    Saturday,
112}
113
114impl Weekday {
115    /// Converts a Sunday-based weekday number (0 = Sunday … 6 = Saturday) to `Weekday`.
116    pub const fn from_sunday_0_based(n: u8) -> Option<Self> {
117        match n {
118            0 => Some(Weekday::Sunday),
119            1 => Some(Weekday::Monday),
120            2 => Some(Weekday::Tuesday),
121            3 => Some(Weekday::Wednesday),
122            4 => Some(Weekday::Thursday),
123            5 => Some(Weekday::Friday),
124            6 => Some(Weekday::Saturday),
125            _ => None,
126        }
127    }
128
129    /// Converts a Monday-based weekday number (1 = Monday … 7 = Sunday) to `Weekday`.
130    pub const fn from_monday_1_based(n: u8) -> Option<Self> {
131        match n {
132            1 => Some(Weekday::Monday),
133            2 => Some(Weekday::Tuesday),
134            3 => Some(Weekday::Wednesday),
135            4 => Some(Weekday::Thursday),
136            5 => Some(Weekday::Friday),
137            6 => Some(Weekday::Saturday),
138            7 => Some(Weekday::Sunday),
139            _ => None,
140        }
141    }
142
143    /// Sunday-based weekday number (0 = Sunday … 6 = Saturday).
144    pub const fn wkday_sun_0_based(self) -> u8 {
145        match self {
146            Weekday::Sunday => 0,
147            Weekday::Monday => 1,
148            Weekday::Tuesday => 2,
149            Weekday::Wednesday => 3,
150            Weekday::Thursday => 4,
151            Weekday::Friday => 5,
152            Weekday::Saturday => 6,
153        }
154    }
155
156    /// Sunday-based weekday number (1 = Sunday … 7 = Saturday).
157    pub const fn wkday_sun_1_based(self) -> u8 {
158        match self {
159            Weekday::Sunday => 1,
160            Weekday::Monday => 2,
161            Weekday::Tuesday => 3,
162            Weekday::Wednesday => 4,
163            Weekday::Thursday => 5,
164            Weekday::Friday => 6,
165            Weekday::Saturday => 7,
166        }
167    }
168
169    /// Monday-based weekday number (0 = Monday … 6 = Sunday).
170    pub const fn wkday_mon_0_based(self) -> u8 {
171        match self {
172            Weekday::Monday => 0,
173            Weekday::Tuesday => 1,
174            Weekday::Wednesday => 2,
175            Weekday::Thursday => 3,
176            Weekday::Friday => 4,
177            Weekday::Saturday => 5,
178            Weekday::Sunday => 6,
179        }
180    }
181
182    /// Monday-based weekday number (1 = Monday … 7 = Sunday).
183    pub const fn wkday_mon_1_based(self) -> u8 {
184        match self {
185            Weekday::Monday => 1,
186            Weekday::Tuesday => 2,
187            Weekday::Wednesday => 3,
188            Weekday::Thursday => 4,
189            Weekday::Friday => 5,
190            Weekday::Saturday => 6,
191            Weekday::Sunday => 7,
192        }
193    }
194}
195
196/// Timezone offset representation.
197#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
198#[cfg_attr(feature = "js", derive(tsify::Tsify))]
199#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
200pub enum Offset {
201    #[default]
202    Utc,
203    None,
204    /// Fixed offset from UTC in seconds
205    Fixed(i32),
206}