icu_datetime/format/
input.rs

1// This file is part of ICU4X. For terms of use, please see the file
2// called LICENSE at the top level of the ICU4X source tree
3// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5//! A collection of utilities for representing and working with dates as an input to
6//! formatting operations.
7
8use crate::scaffold::*;
9use icu_calendar::types::{DayOfYear, RataDie};
10use icu_calendar::{AsCalendar, Calendar};
11use icu_time::scaffold::IntoOption;
12use icu_time::zone::ZoneNameTimestamp;
13use icu_time::{Hour, Minute, Nanosecond, Second};
14
15use icu_calendar::Date;
16use icu_time::{zone::UtcOffset, Time, TimeZone};
17
18// TODO(#2630) fix up imports to directly import from icu_calendar
19pub(crate) use icu_calendar::types::{DayOfMonth, MonthInfo, Weekday, YearInfo};
20
21#[cfg(doc)]
22use crate::input::*;
23
24/// An input bag with all possible datetime input fields.
25///
26/// Each input field may or may not be required, depending on the field set
27/// and the options.
28#[derive(Debug, Copy, Clone, Default)]
29#[non_exhaustive]
30pub struct DateTimeInputUnchecked {
31    /// The year, required for field sets with years (`Y`).
32    pub(crate) year: Option<YearInfo>,
33    /// The month, required for field sets with months (`M`)
34    pub(crate) month: Option<MonthInfo>,
35    /// The day-of-month, required for field sets with days (`D`).
36    pub(crate) day_of_month: Option<DayOfMonth>,
37    /// The weekday, required for field sets with weekdays (`E`).
38    pub(crate) iso_weekday: Option<Weekday>,
39    /// The day-of-year, required for field sets with weeks.
40    pub(crate) day_of_year: Option<DayOfYear>,
41    /// The RataDie of the day
42    pub(crate) rata_die: Option<RataDie>,
43    /// The hour, required for field sets with times (`T`).
44    pub(crate) hour: Option<Hour>,
45    /// The minute, required for field sets with times (`T`).
46    pub(crate) minute: Option<Minute>,
47    /// The second, required for field sets with times (`T`).
48    pub(crate) second: Option<Second>,
49    /// The subsecond, required for field sets with times (`T`).
50    pub(crate) subsecond: Option<Nanosecond>,
51    /// The time zone ID, required for field sets with
52    /// certain time zone styles.
53    pub(crate) zone_id: Option<TimeZone>,
54    /// The time zone UTC offset, required for field sets with
55    /// certain time zone styles.
56    pub(crate) zone_offset: Option<UtcOffset>,
57    /// The local ISO time, required for field sets with
58    /// certain time zone styles.
59    pub(crate) zone_name_timestamp: Option<ZoneNameTimestamp>,
60}
61
62impl DateTimeInputUnchecked {
63    /// Sets all fields from a [`Date`] input.
64    ///
65    /// This method does not check the calendar of the date! The caller is
66    /// responsible for making sure the calendar matches the formatter.
67    pub fn set_date_fields_unchecked<C: Calendar, A: AsCalendar<Calendar = C>>(
68        &mut self,
69        date_in_calendar: Date<A>,
70    ) {
71        self.year = Some(date_in_calendar.year());
72        self.month = Some(date_in_calendar.month());
73        self.day_of_month = Some(date_in_calendar.day_of_month());
74        self.iso_weekday = Some(date_in_calendar.day_of_week());
75        self.day_of_year = Some(date_in_calendar.day_of_year());
76    }
77
78    /// Sets all fields from a [`Time`] input.
79    pub fn set_time_fields(&mut self, time: Time) {
80        self.hour = Some(time.hour);
81        self.minute = Some(time.minute);
82        self.second = Some(time.second);
83        self.subsecond = Some(time.subsecond);
84    }
85
86    /// Sets the time zone UTC offset.
87    pub fn set_time_zone_utc_offset(&mut self, utc_offset: UtcOffset) {
88        self.zone_offset = Some(utc_offset);
89    }
90
91    /// Sets the time zone ID.
92    pub fn set_time_zone_id(&mut self, id: TimeZone) {
93        self.zone_id = Some(id);
94    }
95
96    /// Sets the local time for time zone name resolution.
97    pub fn set_time_zone_name_timestamp(&mut self, timestamp: ZoneNameTimestamp) {
98        self.zone_name_timestamp = Some(timestamp);
99    }
100
101    /// No-op
102    #[deprecated]
103    pub fn set_time_zone_variant(&mut self, _zone_variant: icu_time::zone::TimeZoneVariant) {}
104
105    /// Construct given neo date input instances.
106    pub(crate) fn extract_from_neo_input<D, T, Z, I>(input: &I) -> Self
107    where
108        D: DateInputMarkers,
109        T: TimeMarkers,
110        Z: ZoneMarkers,
111        I: ?Sized
112            + GetField<D::YearInput>
113            + GetField<D::MonthInput>
114            + GetField<D::DayOfMonthInput>
115            + GetField<D::DayOfWeekInput>
116            + GetField<D::DayOfYearInput>
117            + GetField<D::RataDieInput>
118            + GetField<T::HourInput>
119            + GetField<T::MinuteInput>
120            + GetField<T::SecondInput>
121            + GetField<T::NanosecondInput>
122            + GetField<Z::TimeZoneIdInput>
123            + GetField<Z::TimeZoneOffsetInput>
124            + GetField<Z::TimeZoneNameTimestampInput>,
125    {
126        Self {
127            year: GetField::<D::YearInput>::get_field(input).into_option(),
128            month: GetField::<D::MonthInput>::get_field(input).into_option(),
129            day_of_month: GetField::<D::DayOfMonthInput>::get_field(input).into_option(),
130            iso_weekday: GetField::<D::DayOfWeekInput>::get_field(input).into_option(),
131            day_of_year: GetField::<D::DayOfYearInput>::get_field(input).into_option(),
132            rata_die: GetField::<D::RataDieInput>::get_field(input).into_option(),
133            hour: GetField::<T::HourInput>::get_field(input).into_option(),
134            minute: GetField::<T::MinuteInput>::get_field(input).into_option(),
135            second: GetField::<T::SecondInput>::get_field(input).into_option(),
136            subsecond: GetField::<T::NanosecondInput>::get_field(input).into_option(),
137            zone_id: GetField::<Z::TimeZoneIdInput>::get_field(input).into_option(),
138            zone_offset: GetField::<Z::TimeZoneOffsetInput>::get_field(input).into_option(),
139            zone_name_timestamp: GetField::<Z::TimeZoneNameTimestampInput>::get_field(input)
140                .into_option(),
141        }
142    }
143}