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}