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: Option<u8>,
43    /// Minute of the hour (0–59).
44    pub min: Option<u8>,
45    /// Second of the minute (0–60). Value 60 is used for leap seconds.
46    pub sec: Option<u8>,
47    /// Attoseconds (0 ≤ value < 10¹⁸).
48    pub attos: Option<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    /// Whether this instant represents a leap second.
54    pub is_leap_sec: bool,
55    /// The time scale this value belongs to (TAI, UTC, etc.).
56    pub scale: Scale,
57    /// Day of the week.
58    pub wkday: Option<Weekday>,
59    /// Day of the year (1–366), corresponding to `%j`.
60    pub day_of_yr: Option<u16>,
61    /// ISO week year (`%G` / `%g`).
62    pub iso_wk_yr: Option<i64>,
63    /// ISO week number (1–53), corresponding to `%V`.
64    pub iso_wk: Option<u8>,
65    /// Week number with Sunday as first day of week (0–53), `%U`.
66    pub wk_sun: Option<u8>,
67    /// Week number with Monday as first day of week (0–53), `%W`.
68    pub wk_mon: Option<u8>,
69    /// AM / PM indicator.
70    pub meridiem: Option<Meridiem>,
71    /// Unix timestamp in seconds (`%s`).
72    pub unix_timestamp_seconds: Option<i64>,
73}
74
75impl TimeParts {
76    #[inline]
77    pub fn new_utc() -> Self {
78        Self {
79            scale: Scale::UTC,
80            ..Default::default()
81        }
82    }
83
84    /// Sets the IANA timezone name.
85    #[inline]
86    pub fn set_iana_name(&mut self, name: Option<&str>) -> &mut Self {
87        self.iana_name = name.map(LiteStr::new);
88        self
89    }
90}
91
92/// AM / PM indicator.
93#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
94#[cfg_attr(feature = "js", derive(tsify::Tsify))]
95#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
96pub enum Meridiem {
97    #[default]
98    AM,
99    PM,
100}
101
102/// Day of the week. Default is set to Sunday.
103#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
104#[cfg_attr(feature = "js", derive(tsify::Tsify))]
105#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
106pub enum Weekday {
107    #[default]
108    Sunday,
109    Monday,
110    Tuesday,
111    Wednesday,
112    Thursday,
113    Friday,
114    Saturday,
115}
116
117impl Weekday {
118    /// Converts a Sunday-based weekday number (0 = Sunday … 6 = Saturday) to `Weekday`.
119    #[inline]
120    pub const fn from_sunday_zero_offset(n: u8) -> Option<Self> {
121        match n {
122            0 => Some(Weekday::Sunday),
123            1 => Some(Weekday::Monday),
124            2 => Some(Weekday::Tuesday),
125            3 => Some(Weekday::Wednesday),
126            4 => Some(Weekday::Thursday),
127            5 => Some(Weekday::Friday),
128            6 => Some(Weekday::Saturday),
129            _ => None,
130        }
131    }
132
133    /// Converts a Monday-based weekday number (1 = Monday … 7 = Sunday) to `Weekday`.
134    #[inline]
135    pub const fn from_monday_one_offset(n: u8) -> Option<Self> {
136        match n {
137            1 => Some(Weekday::Monday),
138            2 => Some(Weekday::Tuesday),
139            3 => Some(Weekday::Wednesday),
140            4 => Some(Weekday::Thursday),
141            5 => Some(Weekday::Friday),
142            6 => Some(Weekday::Saturday),
143            7 => Some(Weekday::Sunday),
144            _ => None,
145        }
146    }
147
148    /// Sunday-based weekday number (0 = Sunday … 6 = Saturday).
149    #[inline]
150    pub const fn wk_sun(self) -> u8 {
151        match self {
152            Weekday::Sunday => 0,
153            Weekday::Monday => 1,
154            Weekday::Tuesday => 2,
155            Weekday::Wednesday => 3,
156            Weekday::Thursday => 4,
157            Weekday::Friday => 5,
158            Weekday::Saturday => 6,
159        }
160    }
161
162    /// Monday-based weekday number (1 = Monday … 7 = Sunday).
163    #[inline]
164    pub const fn wk_mon(self) -> u8 {
165        match self {
166            Weekday::Monday => 1,
167            Weekday::Tuesday => 2,
168            Weekday::Wednesday => 3,
169            Weekday::Thursday => 4,
170            Weekday::Friday => 5,
171            Weekday::Saturday => 6,
172            Weekday::Sunday => 7,
173        }
174    }
175}
176
177/// Timezone offset representation.
178#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
179#[cfg_attr(feature = "js", derive(tsify::Tsify))]
180#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
181pub enum Offset {
182    #[default]
183    Utc,
184    None,
185    /// Fixed offset from UTC in seconds
186    Fixed(i32),
187}