Module icu_datetime::neo_marker
source · Expand description
Temporary module for neo formatter markers.
§Examples
§Alignment
By default, datetimes are formatted for a variable-width context. You can give a hint that the strings will be displayed in a column-like context, which will coerce numerics to be padded with zeros.
use icu::calendar::Date;
use icu::calendar::Gregorian;
use icu::datetime::neo::NeoOptions;
use icu::datetime::neo::TypedNeoFormatter;
use icu::datetime::neo_marker::NeoYearMonthDayMarker;
use icu::datetime::neo_skeleton::Alignment;
use icu::datetime::neo_skeleton::NeoSkeletonLength;
use icu::locale::locale;
use writeable::assert_try_writeable_eq;
let plain_formatter =
TypedNeoFormatter::<Gregorian, NeoYearMonthDayMarker>::try_new(
&locale!("en-US").into(),
NeoSkeletonLength::Short.into(),
)
.unwrap();
let column_formatter =
TypedNeoFormatter::<Gregorian, NeoYearMonthDayMarker>::try_new(
&locale!("en-US").into(),
{
let mut options = NeoOptions::from(NeoSkeletonLength::Short);
options.alignment = Some(Alignment::Column);
options
}
)
.unwrap();
// By default, en-US does not pad the month and day with zeros.
assert_try_writeable_eq!(
plain_formatter.format(&Date::try_new_gregorian_date(2025, 1, 1).unwrap()),
"1/1/25"
);
// The column alignment option hints that they should be padded.
assert_try_writeable_eq!(
column_formatter.format(&Date::try_new_gregorian_date(2025, 1, 1).unwrap()),
"01/01/25"
);
§Era Display
The era field can be toggled on and off using the EraDisplay
option.
use icu::calendar::Date;
use icu::calendar::Gregorian;
use icu::datetime::neo::NeoOptions;
use icu::datetime::neo::TypedNeoFormatter;
use icu::datetime::neo_marker::NeoEraYearMonthDayMarker;
use icu::datetime::neo_skeleton::EraDisplay;
use icu::datetime::neo_skeleton::NeoSkeletonLength;
use icu::locale::locale;
use writeable::assert_try_writeable_eq;
let formatter =
TypedNeoFormatter::<Gregorian, NeoEraYearMonthDayMarker>::try_new(
&locale!("en-US").into(),
{
let mut options = NeoOptions::from(NeoSkeletonLength::Medium);
options.era_display = Some(EraDisplay::Auto);
options
}
)
.unwrap();
// Era displayed when needed for disambiguation,
// such as years before year 0 and small year numbers:
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian_date(-1000, 1, 1).unwrap()),
"Jan 1, 1001 BC"
);
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian_date(77, 1, 1).unwrap()),
"Jan 1, 77 AD"
);
// Era elided for modern years:
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian_date(2023, 12, 20).unwrap()),
"Dec 20, 2023"
);
let formatter =
TypedNeoFormatter::<Gregorian, NeoEraYearMonthDayMarker>::try_new(
&locale!("en-US").into(),
{
let mut options = NeoOptions::from(NeoSkeletonLength::Medium);
options.era_display = Some(EraDisplay::Always);
options
}
)
.unwrap();
// Era still displayed in cases with ambiguity:
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian_date(-1000, 1, 1).unwrap()),
"Jan 1, 1001 BC"
);
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian_date(77, 1, 1).unwrap()),
"Jan 1, 77 AD"
);
// But now it is shown even on modern years:
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian_date(2023, 12, 20).unwrap()),
"Dec 20, 2023 AD"
);
§Hour Cycle
Hours can be switched between 12-hour and 24-hour time via the u-hc
locale keyword.
use icu::calendar::Time;
use icu::datetime::neo::TypedNeoFormatter;
use icu::datetime::neo_marker::NeoHourMinuteMarker;
use icu::datetime::neo_skeleton::NeoSkeletonLength;
use icu::datetime::NeverCalendar;
use icu::locale::locale;
use writeable::assert_try_writeable_eq;
// By default, en-US uses 12-hour time and fr-FR uses 24-hour time,
// but we can set overrides.
let formatter =
TypedNeoFormatter::<NeverCalendar, NeoHourMinuteMarker>::try_new(
&locale!("en-US-u-hc-h12").into(),
NeoSkeletonLength::Short.into(),
)
.unwrap();
assert_try_writeable_eq!(
formatter.format(&Time::try_new(16, 12, 20, 0).unwrap()),
"4:12 PM"
);
let formatter =
TypedNeoFormatter::<NeverCalendar, NeoHourMinuteMarker>::try_new(
&locale!("en-US-u-hc-h23").into(),
NeoSkeletonLength::Short.into(),
)
.unwrap();
assert_try_writeable_eq!(
formatter.format(&Time::try_new(16, 12, 20, 0).unwrap()),
"16:12"
);
let formatter =
TypedNeoFormatter::<NeverCalendar, NeoHourMinuteMarker>::try_new(
&locale!("fr-FR-u-hc-h12").into(),
NeoSkeletonLength::Short.into(),
)
.unwrap();
assert_try_writeable_eq!(
formatter.format(&Time::try_new(16, 12, 20, 0).unwrap()),
"4:12 PM"
);
let formatter =
TypedNeoFormatter::<NeverCalendar, NeoHourMinuteMarker>::try_new(
&locale!("fr-FR-u-hc-h23").into(),
NeoSkeletonLength::Short.into(),
)
.unwrap();
assert_try_writeable_eq!(
formatter.format(&Time::try_new(16, 12, 20, 0).unwrap()),
"16:12"
);
Hour cycles h11
and h24
are supported, too:
use icu::calendar::Time;
use icu::datetime::neo::TypedNeoFormatter;
use icu::datetime::neo_marker::NeoHourMinuteMarker;
use icu::datetime::neo_skeleton::NeoSkeletonLength;
use icu::datetime::NeverCalendar;
use icu::locale::locale;
use writeable::assert_try_writeable_eq;
let formatter =
TypedNeoFormatter::<NeverCalendar, NeoHourMinuteMarker>::try_new(
&locale!("und-u-hc-h11").into(),
NeoSkeletonLength::Short.into(),
)
.unwrap();
assert_try_writeable_eq!(
formatter.format(&Time::try_new(0, 0, 0, 0).unwrap()),
"0:00 AM"
);
let formatter =
TypedNeoFormatter::<NeverCalendar, NeoHourMinuteMarker>::try_new(
&locale!("und-u-hc-h24").into(),
NeoSkeletonLength::Short.into(),
)
.unwrap();
assert_try_writeable_eq!(
formatter.format(&Time::try_new(0, 0, 0, 0).unwrap()),
"24:00"
);
§Fractional Second Digits
Times can be displayed with a custom number of fractional digits from 0-9:
use icu::calendar::Gregorian;
use icu::calendar::Time;
use icu::datetime::neo::NeoOptions;
use icu::datetime::neo::TypedNeoFormatter;
use icu::datetime::neo_marker::NeoHourMinuteSecondMarker;
use icu::datetime::neo_skeleton::NeoSkeletonLength;
use icu::datetime::neo_skeleton::FractionalSecondDigits;
use icu::datetime::NeverCalendar;
use icu::locale::locale;
use writeable::assert_try_writeable_eq;
let formatter =
TypedNeoFormatter::<NeverCalendar, NeoHourMinuteSecondMarker>::try_new(
&locale!("en-US").into(),
{
let mut options = NeoOptions::from(NeoSkeletonLength::Short);
options.fractional_second_digits = Some(FractionalSecondDigits::F2);
options
}
)
.unwrap();
assert_try_writeable_eq!(
formatter.format(&Time::try_new(16, 12, 20, 543200000).unwrap()),
"4:12:20.54 PM"
);
§Time Zone Formatting
Here, we configure a NeoFormatter
to format with generic non-location short,
which falls back to the offset when unavailable (see NeoTimeZoneGenericShortMarker
).
use icu::calendar::DateTime;
use icu::timezone::{CustomTimeZone, MetazoneCalculator, TimeZoneIdMapper, TimeZoneBcp47Id};
use icu::datetime::neo::TypedNeoFormatter;
use icu::datetime::neo_marker::NeoTimeZoneGenericShortMarker;
use icu::datetime::NeverCalendar;
use icu::locale::locale;
use tinystr::tinystr;
use writeable::assert_try_writeable_eq;
// Set up the time zone. Note: the inputs here are
// 1. The offset
// 2. The IANA time zone ID
// 3. A datetime (for metazone resolution)
// 4. Note: we do not need the zone variant because of `load_generic_*()`
// Set up the Metazone calculator, time zone ID mapper,
// and the DateTime to use in calculation
let mzc = MetazoneCalculator::new();
let mapper = TimeZoneIdMapper::new();
let datetime = DateTime::try_new_iso_datetime(2022, 8, 29, 0, 0, 0)
.unwrap();
// Set up the formatter
let mut tzf = TypedNeoFormatter::<NeverCalendar, NeoTimeZoneGenericShortMarker>::try_new(
&locale!("en").into(),
// Length does not matter here: it is specified in the type parameter
Default::default(),
)
.unwrap();
// "uschi" - has metazone symbol data for generic_non_location_short
let mut time_zone = "-0600".parse::<CustomTimeZone>().unwrap();
time_zone.time_zone_id = mapper.as_borrowed().iana_to_bcp47("America/Chicago");
time_zone.maybe_calculate_metazone(&mzc, &datetime);
assert_try_writeable_eq!(
tzf.format(&time_zone),
"CT"
);
// "ushnl" - has time zone override symbol data for generic_non_location_short
let mut time_zone = "-1000".parse::<CustomTimeZone>().unwrap();
time_zone.time_zone_id = Some(TimeZoneBcp47Id(tinystr!(8, "ushnl")));
time_zone.maybe_calculate_metazone(&mzc, &datetime);
assert_try_writeable_eq!(
tzf.format(&time_zone),
"HST"
);
// Raw offset - used when metazone is not available
let mut time_zone = "+0530".parse::<CustomTimeZone>().unwrap();
assert_try_writeable_eq!(
tzf.format(&time_zone),
"GMT+05:30"
);
Structs§
- A struct that supports formatting both a date and a time.
- Struct representing the absence of a datetime formatting field.
Enums§
- Implementation of
CalMarkers
that includes data for all calendars. - “May 17, 2024” ⇒ locale-dependent date fields
- “3:47:50 PM” ⇒ locale-dependent time fields
- “May 17, 2024” ⇒ year, month, and day (year always with full precision)
- “3:47 PM” ⇒ hour and minute (locale-dependent hour cycle)
- “3:47:50 PM” ⇒ hour, minute, and second (locale-dependent hour cycle)
- A struct implementing traits for never loading data.
- “Central Time” ⇒ generic time zone with a longer length, or location if unavailable
- “CT” ⇒ generic time zone with inherited length, or location if unavailable
- “CT” ⇒ generic time zone with a shorter length, or location if unavailable
- “Chicago Time” ⇒ location time zone
- “GMT-05:00” ⇒ UTC offset with a longer length
- “GMT-05:00” ⇒ UTC offset with inherited length
- “GMT-05:00” ⇒ UTC offset with a shorter length
- “Central Daylight Time” ⇒ specific time zone with a longer length, or raw offset if unavailable
- “CDT” ⇒ specific time zone with inherited length, or raw offset if unavailable
- “CDT” ⇒ specific time zone with a shorter length, or raw offset if unavailable
- “5/17/24” ⇒ year, month, and day (year might be abbreviated)
- “May 2024” ⇒ year and month (era elided when possible)
- Implementation of
CalMarkers
that includes data for no calendars.
Traits§
- Trait to consolidate input markers.
- A collection of marker types associated with all calendars.
- A type that can be converted into a specific calendar system.
- A trait associating types for date formatting in any calendar (data markers only).
- A trait associating types for date formatting in any calendar (input types only).
- A trait associating constants and types implementing various other traits required for datetime formatting.
- A trait associating
NeoComponents
. - A trait associating
NeoDateComponents
. - A trait associating
NeoDayComponents
. - A trait associating
NeoTimeComponents
. - A trait associating
NeoTimeZoneSkeleton
. - A type that might be compatible with a specific calendar system.
- An input associated with a specific calendar.
- Trait for components that can be formatted at runtime.
- A type that can return a certain field
T
. - A trait associating types for time formatting (input types and data markers).
- A trait associating types for date formatting in a specific calendar (data markers only).
- A trait associating types for time zone formatting (input types and data markers).
Type Aliases§
- “May 17, 2024, 3:47:50 PM” ⇒ locale-dependent date and time fields
- “May 17, 2024, 3:47 PM” ⇒ locale-dependent date and time fields
- “May 17, 2024, 3:47:50 PM GMT” ⇒ locale-dependent date and time fields with a time zone