icu_datetime/
combo.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
5use crate::{provider::neo::*, scaffold::*};
6
7/// Struct for combining date/time fields with zone fields.
8///
9/// This struct produces "composite field sets" as defined in UTS 35.
10/// See [`fieldsets`](crate::fieldsets).
11///
12/// # Examples
13///
14/// The only way to construct a combo field set (in this case, weekday with location-based zone):
15///
16/// ```
17/// use icu::datetime::fieldsets::{zone::Location, Combo, E};
18///
19/// let field_set = E::long().with_zone(Location);
20/// ```
21///
22/// Format the weekday, hour, and location-based zone:
23///
24/// ```
25/// use icu::datetime::fieldsets::{self, zone, Combo};
26/// use icu::datetime::input::ZonedDateTime;
27/// use icu::datetime::DateTimeFormatter;
28/// use icu::locale::locale;
29/// use icu::time::zone::IanaParser;
30/// use writeable::assert_writeable_eq;
31///
32/// // Note: Combo type can be elided, but it is shown here for demonstration
33/// let formatter =
34///     DateTimeFormatter::<Combo<fieldsets::ET, zone::Location>>::try_new(
35///         locale!("en-US").into(),
36///         fieldsets::E::short()
37///             .with_time_hm()
38///             .with_zone(zone::Location),
39///     )
40///     .unwrap();
41///
42/// let zdt = ZonedDateTime::try_location_only_from_str(
43///     "2024-10-18T15:44[America/Los_Angeles]",
44///     formatter.calendar(),
45///     IanaParser::new(),
46/// )
47/// .unwrap();
48///
49/// assert_writeable_eq!(
50///     formatter.format(&zdt),
51///     "Fri, 3:44 PM Los Angeles Time"
52/// );
53/// ```
54///
55/// Same thing with a fixed calendar formatter:
56///
57/// ```
58/// use icu::calendar::Gregorian;
59/// use icu::datetime::fieldsets::{self, zone, Combo};
60/// use icu::datetime::input::ZonedDateTime;
61/// use icu::datetime::FixedCalendarDateTimeFormatter;
62/// use icu::locale::locale;
63/// use icu::time::zone::IanaParser;
64/// use writeable::assert_writeable_eq;
65///
66/// // Note: Combo type can be elided, but it is shown here for demonstration
67/// let formatter = FixedCalendarDateTimeFormatter::<
68///     _,
69///     Combo<fieldsets::ET, zone::Location>,
70/// >::try_new(
71///     locale!("en-US").into(),
72///     fieldsets::E::short()
73///         .with_time_hm()
74///         .with_zone(zone::Location),
75/// )
76/// .unwrap();
77///
78/// let zdt = ZonedDateTime::try_location_only_from_str(
79///     "2024-10-18T15:44[America/Los_Angeles]",
80///     Gregorian,
81///     IanaParser::new(),
82/// )
83/// .unwrap();
84///
85/// assert_writeable_eq!(
86///     formatter.format(&zdt),
87///     "Fri, 3:44 PM Los Angeles Time"
88/// );
89/// ```
90///
91/// Mix a dynamic [`DateFieldSet`](crate::fieldsets::enums::DateFieldSet)
92/// with a static time zone:
93///
94/// ```
95/// use icu::datetime::fieldsets::{
96///     enums::DateFieldSet, zone::GenericShort, Combo, YMD,
97/// };
98/// use icu::datetime::input::ZonedDateTime;
99/// use icu::datetime::DateTimeFormatter;
100/// use icu::locale::locale;
101/// use icu::time::zone::IanaParser;
102/// use writeable::assert_writeable_eq;
103///
104/// // Note: Combo type can be elided, but it is shown here for demonstration
105/// let formatter =
106///     DateTimeFormatter::<Combo<DateFieldSet, GenericShort>>::try_new(
107///         locale!("en-US").into(),
108///         DateFieldSet::YMD(YMD::long()).with_zone(GenericShort),
109///     )
110///     .unwrap();
111///
112/// let zdt = ZonedDateTime::try_location_only_from_str(
113///     "2024-10-18T15:44[America/Los_Angeles]",
114///     formatter.calendar(),
115///     IanaParser::new(),
116/// )
117/// .unwrap();
118///
119/// assert_writeable_eq!(formatter.format(&zdt), "October 18, 2024 PT");
120/// ```
121///
122/// Format with a time of day and long time zone:
123///
124/// ```
125/// use icu::calendar::Gregorian;
126/// use icu::datetime::fieldsets::{zone::SpecificLong, T};
127/// use icu::datetime::input::ZonedDateTime;
128/// use icu::datetime::FixedCalendarDateTimeFormatter;
129/// use icu::locale::locale;
130/// use icu::time::zone::{IanaParser, VariantOffsetsCalculator};
131/// use writeable::assert_writeable_eq;
132///
133/// let formatter = FixedCalendarDateTimeFormatter::try_new(
134///     locale!("en-US").into(),
135///     T::medium().with_zone(SpecificLong),
136/// )
137/// .unwrap();
138///
139/// let zdt = ZonedDateTime::try_full_from_str(
140///     "2024-10-18T15:44-0700[America/Los_Angeles]",
141///     Gregorian,
142///     IanaParser::new(),
143///     VariantOffsetsCalculator::new(),
144/// )
145/// .unwrap();
146///
147/// assert_writeable_eq!(
148///     formatter.format(&zdt),
149///     "3:44:00 PM Pacific Daylight Time"
150/// );
151/// ```
152#[derive(Debug, Copy, Clone, PartialEq, Eq)]
153pub struct Combo<DT, Z> {
154    date_time_field_set: DT,
155    zone_field_set: Z,
156}
157
158impl<DT, Z> Combo<DT, Z> {
159    #[inline]
160    pub(crate) const fn new(date_time_field_set: DT, zone_field_set: Z) -> Self {
161        Self {
162            date_time_field_set,
163            zone_field_set,
164        }
165    }
166}
167
168impl<DT, Z> UnstableSealed for Combo<DT, Z> {}
169
170impl<DT, Z> Combo<DT, Z> {
171    #[inline]
172    pub(crate) fn dt(self) -> DT {
173        self.date_time_field_set
174    }
175    #[inline]
176    pub(crate) fn z(self) -> Z {
177        self.zone_field_set
178    }
179}
180
181impl<DT, Z> DateTimeNamesMarker for Combo<DT, Z>
182where
183    DT: DateTimeNamesMarker,
184    Z: DateTimeNamesMarker,
185{
186    type YearNames = DT::YearNames;
187    type MonthNames = DT::MonthNames;
188    type WeekdayNames = DT::WeekdayNames;
189    type DayPeriodNames = DT::DayPeriodNames;
190    type ZoneEssentials = Z::ZoneEssentials;
191    type ZoneLocations = Z::ZoneLocations;
192    type ZoneLocationsRoot = Z::ZoneLocationsRoot;
193    type ZoneExemplars = Z::ZoneExemplars;
194    type ZoneExemplarsRoot = Z::ZoneExemplarsRoot;
195    type ZoneGenericLong = Z::ZoneGenericLong;
196    type ZoneGenericShort = Z::ZoneGenericShort;
197    type ZoneStandardLong = Z::ZoneStandardLong;
198    type ZoneSpecificLong = Z::ZoneSpecificLong;
199    type ZoneSpecificShort = Z::ZoneSpecificShort;
200    type MetazoneLookup = Z::MetazoneLookup;
201}
202
203impl<DT, Z> DateTimeMarkers for Combo<DT, Z>
204where
205    DT: DateTimeMarkers,
206    Z: DateTimeMarkers,
207{
208    type D = DT::D;
209    type T = DT::T;
210    type Z = Z::Z;
211    type GluePatternV1 = datetime_marker_helper!(@glue, yes);
212}