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::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, _>::try_new(
&locale!("en-US").into(),
NeoYearMonthDayMarker::with_length(NeoSkeletonLength::Short),
)
.unwrap();
let column_formatter = TypedNeoFormatter::<Gregorian, _>::try_new(
&locale!("en-US").into(),
NeoYearMonthDayMarker::with_length(NeoSkeletonLength::Short)
.with_alignment(Alignment::Column),
)
.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(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(2025, 1, 1).unwrap()),
"01/01/25"
);
§Year Style
The precision of the rendered year can be adjusted using the YearStyle
option.
use icu::calendar::Date;
use icu::calendar::Gregorian;
use icu::datetime::neo::TypedNeoFormatter;
use icu::datetime::neo_marker::NeoYearMonthDayMarker;
use icu::datetime::neo_skeleton::NeoSkeletonLength;
use icu::datetime::neo_skeleton::YearStyle;
use icu::locale::locale;
use writeable::assert_try_writeable_eq;
let formatter = TypedNeoFormatter::<Gregorian, _>::try_new(
&locale!("en-US").into(),
NeoYearMonthDayMarker::with_length(NeoSkeletonLength::Short)
.with_year_style(YearStyle::Auto),
)
.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(-1000, 1, 1).unwrap()),
"1/1/1001 BC"
);
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian(77, 1, 1).unwrap()),
"1/1/77 AD"
);
// Era elided for modern years:
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian(1900, 1, 1).unwrap()),
"1/1/1900"
);
// Era and century both elided for nearby years:
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian(2025, 1, 1).unwrap()),
"1/1/25"
);
let formatter = TypedNeoFormatter::<Gregorian, _>::try_new(
&locale!("en-US").into(),
NeoYearMonthDayMarker::with_length(NeoSkeletonLength::Short)
.with_year_style(YearStyle::Full),
)
.unwrap();
// Era still displayed in cases with ambiguity:
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian(-1000, 1, 1).unwrap()),
"1/1/1001 BC"
);
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian(77, 1, 1).unwrap()),
"1/1/77 AD"
);
// Era elided for modern years:
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian(1900, 1, 1).unwrap()),
"1/1/1900"
);
// But now we always get a full-precision year:
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian(2025, 1, 1).unwrap()),
"1/1/2025"
);
let formatter = TypedNeoFormatter::<Gregorian, _>::try_new(
&locale!("en-US").into(),
NeoYearMonthDayMarker::with_length(NeoSkeletonLength::Short)
.with_year_style(YearStyle::Always),
)
.unwrap();
// Era still displayed in cases with ambiguity:
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian(-1000, 1, 1).unwrap()),
"1/1/1001 BC"
);
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian(77, 1, 1).unwrap()),
"1/1/77 AD"
);
// But now it is shown even on modern years:
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian(1900, 1, 1).unwrap()),
"1/1/1900 AD"
);
assert_try_writeable_eq!(
formatter.format(&Date::try_new_gregorian(2025, 1, 1).unwrap()),
"1/1/2025 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::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::<(), _>::try_new(
&locale!("en-US-u-hc-h12").into(),
NeoHourMinuteMarker::with_length(NeoSkeletonLength::Short),
)
.unwrap();
assert_try_writeable_eq!(
formatter.format(&Time::try_new(16, 12, 20, 0).unwrap()),
"4:12 PM"
);
let formatter = TypedNeoFormatter::<(), _>::try_new(
&locale!("en-US-u-hc-h23").into(),
NeoHourMinuteMarker::with_length(NeoSkeletonLength::Short),
)
.unwrap();
assert_try_writeable_eq!(
formatter.format(&Time::try_new(16, 12, 20, 0).unwrap()),
"16:12"
);
let formatter = TypedNeoFormatter::<(), _>::try_new(
&locale!("fr-FR-u-hc-h12").into(),
NeoHourMinuteMarker::with_length(NeoSkeletonLength::Short),
)
.unwrap();
assert_try_writeable_eq!(
formatter.format(&Time::try_new(16, 12, 20, 0).unwrap()),
"4:12 PM"
);
let formatter = TypedNeoFormatter::<(), _>::try_new(
&locale!("fr-FR-u-hc-h23").into(),
NeoHourMinuteMarker::with_length(NeoSkeletonLength::Short),
)
.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::locale::locale;
use writeable::assert_try_writeable_eq;
let formatter = TypedNeoFormatter::<(), _>::try_new(
&locale!("und-u-hc-h11").into(),
NeoHourMinuteMarker::with_length(NeoSkeletonLength::Short),
)
.unwrap();
assert_try_writeable_eq!(
formatter.format(&Time::try_new(0, 0, 0, 0).unwrap()),
"0:00 AM"
);
let formatter = TypedNeoFormatter::<(), _>::try_new(
&locale!("und-u-hc-h24").into(),
NeoHourMinuteMarker::with_length(NeoSkeletonLength::Short),
)
.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::TypedNeoFormatter;
use icu::datetime::neo_marker::NeoHourMinuteSecondMarker;
use icu::datetime::neo_skeleton::FractionalSecondDigits;
use icu::datetime::neo_skeleton::NeoSkeletonLength;
use icu::locale::locale;
use writeable::assert_try_writeable_eq;
let formatter = TypedNeoFormatter::<(), _>::try_new(
&locale!("en-US").into(),
NeoHourMinuteSecondMarker::with_length(NeoSkeletonLength::Short)
.with_fractional_second_digits(FractionalSecondDigits::F2),
)
.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 NeoTimeZoneGenericMarker
).
use icu::calendar::{Date, Time};
use icu::timezone::{TimeZoneInfo, UtcOffset, TimeZoneIdMapper, TimeZoneBcp47Id};
use icu::datetime::neo::TypedNeoFormatter;
use icu::datetime::neo_marker::NeoTimeZoneGenericMarker;
use icu::datetime::neo_skeleton::NeoSkeletonLength;
use icu::datetime::DateTimeWriteError;
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 date and time (for non-location name resolution)
// 4. Note: we do not need the zone variant because of `load_generic_*()`
// Set up the time zone ID mapper
let mapper = TimeZoneIdMapper::new();
// Set up the formatter
let mut tzf = TypedNeoFormatter::<(), _>::try_new(
&locale!("en").into(),
NeoTimeZoneGenericMarker::with_length(NeoSkeletonLength::Short),
)
.unwrap();
// "uschi" - has symbol data for generic_non_location_short
let time_zone = TimeZoneInfo::from_id_and_offset(
mapper.as_borrowed().iana_to_bcp47("America/Chicago"),
UtcOffset::from_eighths_of_hour(-5 * 8),
)
.at_time((Date::try_new_iso(2022, 8, 29).unwrap(), Time::midnight()));
assert_try_writeable_eq!(
tzf.format(&time_zone),
"CT"
);
// "ushnl" - has time zone override symbol data for generic_non_location_short
let time_zone = TimeZoneInfo::from_id_and_offset(
mapper.as_borrowed().iana_to_bcp47("Pacific/Honolulu"),
UtcOffset::from_eighths_of_hour(-10 * 8),
)
.at_time((Date::try_new_iso(2022, 8, 29).unwrap(), Time::midnight()));
assert_try_writeable_eq!(
tzf.format(&time_zone),
"HST"
);
// Mis-spelling of "America/Chicago" results in a fallback to GMT format
let time_zone = TimeZoneInfo::from_id_and_offset(
mapper.as_borrowed().iana_to_bcp47("America/Chigagou"),
UtcOffset::from_eighths_of_hour(-5 * 8),
)
.at_time((Date::try_new_iso(2022, 8, 29).unwrap(), Time::midnight()));
assert_try_writeable_eq!(
tzf.format(&time_zone),
"GMT-5"
);
Structs§
- A struct that supports formatting both a date and a time.
- “May 17, 2024” ⇒ locale-dependent date fields
- “3:47:50 PM” ⇒ locale-dependent time fields
- “3:47 PM” ⇒ hour and minute (locale-dependent hour cycle)
- “3:47:50 PM” ⇒ hour, minute, and second (locale-dependent hour cycle)
- “May 17” ⇒ month and day
- “Central Time” ⇒ generic time zone, or location if unavailable
- “CT” ⇒ generic time zone (only short), or location if unavailable
- “Chicago Time” ⇒ location time zone
- “GMT-5” ⇒ UTC offset time zone
- “Central Daylight Time” ⇒ specific time zone, or raw offset if unavailable
- “CDT” ⇒ specific time zone (only short), 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)
Enums§
- A struct implementing traits for never loading data.
Traits§
- Trait to consolidate input markers.
- 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 type that can return a certain field
T
. - A trait associating
NeoComponents
. - A trait associating
NeoDateComponents
. - A trait associating
NeoTimeComponents
. - A trait associating
NeoTimeZoneStyle
. - 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 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
- “17 May 2024, 15:47:50 GMT” ⇒ locale-dependent date and time fields with a time zone
- “17 May 2024, 15:47:50 GMT+1” ⇒ locale-dependent date and time fields with a time zone
- “17 May 2024, 15:47:50 BST” ⇒ locale-dependent date and time fields with a time zone