Skip to content

Commit dcfb305

Browse files
Handle most of Markus' feedback on datetimes (#6423)
Progress on #6242 This does most of the renames and minor doc fixes. I didn't touch anything where I was unsure of what the feedback meant or where it needed more docs work. <!-- Thank you for your pull request to ICU4X! Reminder: try to use [Conventional Comments](https://conventionalcomments.org/) to make comments clearer. Please see https://github.com/unicode-org/icu4x/blob/main/CONTRIBUTING.md for general information on contributing to ICU4X. --> --------- Co-authored-by: Robert Bastian <[email protected]>
1 parent e4db884 commit dcfb305

File tree

13 files changed

+223
-184
lines changed

13 files changed

+223
-184
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Some major changes worth highlighting:
2020
- Rename `wrap_calendar_in_*` APIs to `as_borrowed`, `into_ref_counted`, `into_atomic_ref_counted` (unicode-org#6392)
2121
- `icu_collections`
2222
- Remove some panics from `CodePointTrie`, which should no longer pull in panic machinery even with arithmetic panics enabled for lookup (unicode-org#6204)
23+
- `icu_datetime`
24+
- Rename `.hm()` to `.with_hm()` on fieldsets (unicode-org#6423)
25+
- Length no longer has explicit `repr(u8)` discriminants (unicode-org#6423)
2326
- Data model and providers
2427
- `icu_experimental`
2528
- `dimension`

components/datetime/README.md

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/datetime/src/combo.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::{provider::neo::*, scaffold::*};
1111
///
1212
/// # Examples
1313
///
14-
/// Only one way to construct a combo field set (in this case, weekday with location-based zone):
14+
/// The only way to construct a combo field set (in this case, weekday with location-based zone):
1515
///
1616
/// ```
1717
/// use icu::datetime::fieldsets::{zone::Location, Combo, E};
@@ -22,17 +22,17 @@ use crate::{provider::neo::*, scaffold::*};
2222
/// Format the weekday, hour, and location-based zone:
2323
///
2424
/// ```
25-
/// use icu::datetime::fieldsets::{zone::Location, Combo, ET};
25+
/// use icu::datetime::fieldsets::{self, zone, Combo};
2626
/// use icu::datetime::input::ZonedDateTime;
2727
/// use icu::datetime::DateTimeFormatter;
2828
/// use icu::locale::locale;
2929
/// use icu::time::zone::IanaParser;
3030
/// use writeable::assert_writeable_eq;
3131
///
3232
/// // Note: Combo type can be elided, but it is shown here for demonstration
33-
/// let formatter = DateTimeFormatter::<Combo<ET, Location>>::try_new(
33+
/// let formatter = DateTimeFormatter::<Combo<fieldsets::ET, zone::Location>>::try_new(
3434
/// locale!("en-US").into(),
35-
/// ET::short().hm().zone(Location),
35+
/// fieldsets::ET::short().with_hm().zone(zone::Location),
3636
/// )
3737
/// .unwrap();
3838
///
@@ -53,7 +53,7 @@ use crate::{provider::neo::*, scaffold::*};
5353
///
5454
/// ```
5555
/// use icu::calendar::Gregorian;
56-
/// use icu::datetime::fieldsets::{zone::Location, Combo, ET};
56+
/// use icu::datetime::fieldsets::{self, zone, Combo};
5757
/// use icu::datetime::input::ZonedDateTime;
5858
/// use icu::datetime::FixedCalendarDateTimeFormatter;
5959
/// use icu::locale::locale;
@@ -62,9 +62,9 @@ use crate::{provider::neo::*, scaffold::*};
6262
///
6363
/// // Note: Combo type can be elided, but it is shown here for demonstration
6464
/// let formatter =
65-
/// FixedCalendarDateTimeFormatter::<_, Combo<ET, Location>>::try_new(
65+
/// FixedCalendarDateTimeFormatter::<_, Combo<fieldsets::ET, zone::Location>>::try_new(
6666
/// locale!("en-US").into(),
67-
/// ET::short().hm().zone(Location),
67+
/// fieldsets::ET::short().with_hm().zone(zone::Location),
6868
/// )
6969
/// .unwrap();
7070
///

components/datetime/src/dynamic.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
//!
3939
//! fn get_field_set(should_display_time: bool) -> CompositeDateTimeFieldSet {
4040
//! if should_display_time {
41-
//! let field_set = fieldsets::MDT::medium().hm();
41+
//! let field_set = fieldsets::MDT::medium().with_hm();
4242
//! CompositeDateTimeFieldSet::DateTime(
4343
//! fieldsets::enums::DateAndTimeFieldSet::MDT(field_set),
4444
//! )
@@ -55,15 +55,11 @@
5555
//! time: Time::try_new(16, 0, 0, 0).unwrap(),
5656
//! };
5757
//!
58-
//! let results = [true, false]
59-
//! .map(get_field_set)
60-
//! .map(|field_set| {
61-
//! DateTimeFormatter::try_new(locale!("en-US").into(), field_set)
62-
//! .unwrap()
63-
//! })
64-
//! .map(|formatter| formatter.format(&datetime).to_string());
58+
//! let with_time = DateTimeFormatter::try_new(locale!("en-US").into(), get_field_set(true)).unwrap();
59+
//! let without_time = DateTimeFormatter::try_new(locale!("en-US").into(), get_field_set(false)).unwrap();
6560
//!
66-
//! assert_eq!(results, ["Jan 15, 4:00 PM", "Jan 15"])
61+
//! assert_eq!(with_time.format(&datetime).to_string(), "Jan 15, 4:00 PM");
62+
//! assert_eq!(without_time.format(&datetime).to_string(), "Jan 15");
6763
//! ```
6864
6965
use crate::fieldsets::{builder, Combo};

components/datetime/src/fieldsets.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
//!
3131
//! # Examples
3232
//!
33-
//! Two ways to configure the same field set:
33+
//! There are two ways to configure the same field set:
3434
//!
3535
//! ```
3636
//! use icu::datetime::fieldsets::YMDT;
@@ -255,7 +255,7 @@ macro_rules! impl_marker_with_options {
255255
self
256256
}
257257
/// Sets the time precision to [`TimePrecision::Minute`]
258-
pub fn hm(mut self) -> Self {
258+
pub fn with_hm(mut self) -> Self {
259259
self.time_precision = Some(TimePrecision::Minute);
260260
self
261261
}
@@ -1058,7 +1058,7 @@ impl_time_marker!(
10581058
///
10591059
/// let formatter = NoCalendarFormatter::try_new(
10601060
/// locale!("en-US-u-hc-h12").into(),
1061-
/// T::short().hm(),
1061+
/// T::short().with_hm(),
10621062
/// )
10631063
/// .unwrap();
10641064
/// assert_writeable_eq!(
@@ -1068,7 +1068,7 @@ impl_time_marker!(
10681068
///
10691069
/// let formatter = NoCalendarFormatter::try_new(
10701070
/// locale!("en-US-u-hc-h23").into(),
1071-
/// T::short().hm(),
1071+
/// T::short().with_hm(),
10721072
/// )
10731073
/// .unwrap();
10741074
/// assert_writeable_eq!(
@@ -1078,7 +1078,7 @@ impl_time_marker!(
10781078
///
10791079
/// let formatter = NoCalendarFormatter::try_new(
10801080
/// locale!("fr-FR-u-hc-h12").into(),
1081-
/// T::short().hm(),
1081+
/// T::short().with_hm(),
10821082
/// )
10831083
/// .unwrap();
10841084
/// assert_writeable_eq!(
@@ -1088,7 +1088,7 @@ impl_time_marker!(
10881088
///
10891089
/// let formatter = NoCalendarFormatter::try_new(
10901090
/// locale!("fr-FR-u-hc-h23").into(),
1091-
/// T::short().hm(),
1091+
/// T::short().with_hm(),
10921092
/// )
10931093
/// .unwrap();
10941094
/// assert_writeable_eq!(
@@ -1108,7 +1108,7 @@ impl_time_marker!(
11081108
///
11091109
/// let formatter = NoCalendarFormatter::try_new(
11101110
/// locale!("und-u-hc-h11").into(),
1111-
/// T::short().hm(),
1111+
/// T::short().with_hm(),
11121112
/// )
11131113
/// .unwrap();
11141114
///
@@ -1119,7 +1119,7 @@ impl_time_marker!(
11191119
///
11201120
/// let formatter = NoCalendarFormatter::try_new(
11211121
/// locale!("und-u-hc-h23").into(),
1122-
/// T::short().hm(),
1122+
/// T::short().with_hm(),
11231123
/// )
11241124
/// .unwrap();
11251125
///

components/datetime/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
//! use writeable::assert_writeable_eq;
5858
//!
5959
//! // Field set for year, month, day, hour, and minute with a medium length:
60-
//! let field_set = fieldsets::YMDT::medium().hm();
60+
//! let field_set = fieldsets::YMDT::medium().with_hm();
6161
//!
6262
//! // Create a formatter for Argentinian Spanish:
6363
//! let locale = locale!("es-AR");

components/datetime/src/neo.rs

Lines changed: 80 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,71 @@ size_test!(FixedCalendarDateTimeFormatter<icu_calendar::Gregorian, crate::fields
134134
/// a calendar selected at compile time.
135135
///
136136
/// For more details, please read the [crate root docs][crate].
137+
///
138+
/// # Examples
139+
///
140+
/// Basic usage:
141+
///
142+
/// ```
143+
/// use icu::calendar::cal::JapaneseExtended;
144+
/// use icu::datetime::fieldsets::YMD;
145+
/// use icu::datetime::input::Date;
146+
/// use icu::datetime::FixedCalendarDateTimeFormatter;
147+
/// use icu::locale::locale;
148+
/// use writeable::assert_writeable_eq;
149+
///
150+
/// // The JapaneseExtended generic is inferred by passing this a JapaneseExtended date later
151+
/// let formatter = FixedCalendarDateTimeFormatter::try_new(
152+
/// locale!("es-MX").into(),
153+
/// YMD::long(),
154+
/// )
155+
/// .unwrap();
156+
///
157+
/// assert_writeable_eq!(
158+
/// formatter.format(&Date::try_new_iso(2023, 12, 20).unwrap().to_calendar(JapaneseExtended::new())),
159+
/// "20 de diciembre de 5 Reiwa"
160+
/// );
161+
/// ```
162+
///
163+
/// Mismatched calendars will not compile:
164+
///
165+
/// ```compile_fail
166+
/// use icu::datetime::input::Date;
167+
/// use icu::datetime::input::cal::Buddhist;
168+
/// use icu::datetime::FixedCalendarDateTimeFormatter;
169+
/// use icu::datetime::fieldsets::YMD;
170+
/// use icu::locale::locale;
171+
///
172+
/// let formatter =
173+
/// FixedCalendarDateTimeFormatter::<Buddhist, _>::try_new(
174+
/// locale!("es-MX").into(),
175+
/// YMD::long(),
176+
/// )
177+
/// .unwrap();
178+
///
179+
/// // type mismatch resolving `<Gregorian as AsCalendar>::Calendar == Buddhist`
180+
/// formatter.format(&Date::try_new_gregorian(2023, 12, 20).unwrap());
181+
/// ```
182+
///
183+
/// As with [`DateTimeFormatter`], a time cannot be passed into the formatter when a date is expected:
184+
///
185+
/// ```compile_fail,E0277
186+
/// use icu::datetime::input::Time;
187+
/// use icu::calendar::Gregorian;
188+
/// use icu::datetime::FixedCalendarDateTimeFormatter;
189+
/// use icu::datetime::fieldsets::YMD;
190+
/// use icu::locale::locale;
191+
///
192+
/// let formatter =
193+
/// FixedCalendarDateTimeFormatter::<Gregorian, _>::try_new(
194+
/// locale!("es-MX").into(),
195+
/// YMD::long(),
196+
/// )
197+
/// .unwrap();
198+
///
199+
/// // error[E0277]: the trait bound `Time: AllInputMarkers<fieldsets::YMD>` is not satisfied
200+
/// formatter.format(&Time::midnight());
201+
/// ```
137202
#[doc = typed_neo_year_month_day_formatter_size!()]
138203
#[derive(Debug, Clone)]
139204
pub struct FixedCalendarDateTimeFormatter<C: CldrCalendar, FSet: DateTimeNamesMarker> {
@@ -154,35 +219,6 @@ where
154219
///
155220
/// This ignores the `calendar_kind` preference and instead uses the static calendar type,
156221
/// and supports calendars that are not expressible as preferences, such as [`JapaneseExtended`](icu_calendar::cal::JapaneseExtended).
157-
///
158-
/// Use this constructor for optimal data size and memory use
159-
/// if you know the required datetime components at build time.
160-
/// If you do not know the datetime components until runtime,
161-
/// use a `with_components` constructor.
162-
///
163-
/// # Examples
164-
///
165-
/// Basic usage:
166-
///
167-
/// ```
168-
/// use icu::calendar::cal::JapaneseExtended;
169-
/// use icu::datetime::fieldsets::YMD;
170-
/// use icu::datetime::input::Date;
171-
/// use icu::datetime::FixedCalendarDateTimeFormatter;
172-
/// use icu::locale::locale;
173-
/// use writeable::assert_writeable_eq;
174-
///
175-
/// let formatter = FixedCalendarDateTimeFormatter::try_new(
176-
/// locale!("es-MX").into(),
177-
/// YMD::long(),
178-
/// )
179-
/// .unwrap();
180-
///
181-
/// assert_writeable_eq!(
182-
/// formatter.format(&Date::try_new_iso(2023, 12, 20).unwrap().to_calendar(JapaneseExtended::new())),
183-
/// "20 de diciembre de 5 Reiwa"
184-
/// );
185-
/// ```
186222
#[cfg(feature = "compiled_data")]
187223
pub fn try_new(
188224
prefs: DateTimeFormatterPreferences,
@@ -312,48 +348,6 @@ where
312348
FSet::Z: ZoneMarkers,
313349
{
314350
/// Formats a datetime. Calendars and fields must match at compile time.
315-
///
316-
/// # Examples
317-
///
318-
/// Mismatched calendars will not compile:
319-
///
320-
/// ```compile_fail
321-
/// use icu::datetime::input::Date;
322-
/// use icu::datetime::input::cal::Buddhist;
323-
/// use icu::datetime::FixedCalendarDateTimeFormatter;
324-
/// use icu::datetime::fieldsets::YMD;
325-
/// use icu::locale::locale;
326-
///
327-
/// let formatter =
328-
/// FixedCalendarDateTimeFormatter::<Buddhist, _>::try_new(
329-
/// locale!("es-MX").into(),
330-
/// YMD::long(),
331-
/// )
332-
/// .unwrap();
333-
///
334-
/// // type mismatch resolving `<Gregorian as AsCalendar>::Calendar == Buddhist`
335-
/// formatter.format(&Date::try_new_gregorian(2023, 12, 20).unwrap());
336-
/// ```
337-
///
338-
/// A time cannot be passed into the formatter when a date is expected:
339-
///
340-
/// ```compile_fail,E0277
341-
/// use icu::datetime::input::Time;
342-
/// use icu::calendar::Gregorian;
343-
/// use icu::datetime::FixedCalendarDateTimeFormatter;
344-
/// use icu::datetime::fieldsets::YMD;
345-
/// use icu::locale::locale;
346-
///
347-
/// let formatter =
348-
/// FixedCalendarDateTimeFormatter::<Gregorian, _>::try_new(
349-
/// locale!("es-MX").into(),
350-
/// YMD::long(),
351-
/// )
352-
/// .unwrap();
353-
///
354-
/// // error[E0277]: the trait bound `Time: AllInputMarkers<fieldsets::YMD>` is not satisfied
355-
/// formatter.format(&Time::midnight());
356-
/// ```
357351
pub fn format<I>(&self, input: &I) -> FormattedDateTime
358352
where
359353
I: ?Sized + InFixedCalendar<C> + AllInputMarkers<FSet>,
@@ -470,13 +464,8 @@ where
470464
/// Creates a new [`DateTimeFormatter`] from compiled data with
471465
/// datetime components specified at build time.
472466
///
473-
/// This method will pick the calendar off of the locale; and if unspecified or unknown will fall back to the default
474-
/// calendar for the locale. See [`AnyCalendarKind`] for a list of supported calendars.
475-
///
476-
/// Use this constructor for optimal data size and memory use
477-
/// if you know the required datetime components at build time.
478-
/// If you do not know the datetime components until runtime,
479-
/// use a `with_components` constructor.
467+
/// This method will use the calendar specified in the `calendar_algorithm` preference, or fall back to the default
468+
/// calendar for the preferences if unspecified or unsupported. See [`IntoFormattableAnyCalendar`] for a list of supported calendars.
480469
///
481470
/// ✨ *Enabled with the `compiled_data` Cargo feature.*
482471
///
@@ -954,7 +943,7 @@ impl<C: CldrCalendar, FSet: DateTimeMarkers> FixedCalendarDateTimeFormatter<C, F
954943
/// // Create a simple YMDT formatter:
955944
/// let formatter = FixedCalendarDateTimeFormatter::try_new(
956945
/// locale!("und").into(),
957-
/// YMDT::long().hm().with_alignment(Alignment::Column)
946+
/// YMDT::long().with_hm().with_alignment(Alignment::Column)
958947
/// )
959948
/// .unwrap();
960949
///
@@ -1184,6 +1173,18 @@ impl<FSet: DateTimeMarkers> DateTimeFormatter<FSet> {
11841173
///
11851174
/// # Examples
11861175
///
1176+
/// A [`NoCalendarFormatter`] can be used to format a time:
1177+
///
1178+
/// ```
1179+
/// use icu::datetime::fieldsets::T;
1180+
/// use icu::datetime::NoCalendarFormatter;
1181+
/// use icu::datetime::input::Time;
1182+
/// use icu::locale::locale;
1183+
///
1184+
/// let formatter = NoCalendarFormatter::try_new(locale!("bn").into(), T::long()).unwrap();
1185+
/// assert_eq!(formatter.format(&Time::midnight()).to_string(), "১২:০০:০০ AM");
1186+
/// ```
1187+
///
11871188
/// A [`NoCalendarFormatter`] cannot be constructed with a fieldset that involves dates:
11881189
///
11891190
/// ```

0 commit comments

Comments
 (0)