diff --git a/README.md b/README.md
index 64067fe685e..377c5ef66c6 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,7 @@ use icu::datetime::{DateTimeFormatter, NeoSkeletonLength, fieldsets::YMDT};
use icu::locale::locale;
let dtf = DateTimeFormatter::try_new(
- &locale!("es").into(),
+ locale!("es").into(),
YMDT::long()
)
.expect("locale should be present in compiled data");
diff --git a/components/calendar/src/any_calendar.rs b/components/calendar/src/any_calendar.rs
index b18d8ba2c8a..e847e5ea55d 100644
--- a/components/calendar/src/any_calendar.rs
+++ b/components/calendar/src/any_calendar.rs
@@ -21,12 +21,26 @@ use crate::roc::Roc;
use crate::{types, AsCalendar, Calendar, Date, DateDuration, DateDurationUnit, DateTime, Ref};
use icu_locale_core::extensions::unicode::{key, value, Value};
+use icu_locale_core::preferences::define_preferences;
+use icu_locale_core::preferences::extensions::unicode::keywords::{
+ CalendarAlgorithm, IslamicCalendarAlgorithm,
+};
use icu_locale_core::subtags::language;
use icu_locale_core::Locale;
use icu_provider::prelude::*;
use core::fmt;
+define_preferences!(
+ /// The prefs for datetime formatting.
+ [Copy]
+ AnyCalendarPreferences,
+ {
+ /// The user's preferred calendar system.
+ calendar_algorithm: CalendarAlgorithm
+ }
+);
+
/// This is a calendar that encompasses all formattable calendars supported by this crate
///
/// This allows for the construction of [`Date`] objects that have their calendar known at runtime.
@@ -46,7 +60,7 @@ use core::fmt;
///
/// let locale = locale!("en-u-ca-japanese"); // English with the Japanese calendar
///
-/// let calendar = AnyCalendar::new_for_locale(&locale.into());
+/// let calendar = AnyCalendar::new_for_locale(locale.into());
/// let calendar = Rc::new(calendar); // Avoid cloning it each time
/// // If everything is a local reference, you may use icu::calendar::Ref instead.
///
@@ -748,13 +762,13 @@ impl AnyCalendar {
///
/// [📚 Help choosing a constructor](icu_provider::constructors)
#[cfg(feature = "compiled_data")]
- pub fn new_for_locale(locale: &DataLocale) -> Self {
- let kind = AnyCalendarKind::from_data_locale_with_fallback(locale);
+ pub fn new_for_locale(prefs: AnyCalendarPreferences) -> Self {
+ let kind = AnyCalendarKind::from_prefs_with_fallback(prefs);
Self::new(kind)
}
icu_provider::gen_any_buffer_data_constructors!(
- (locale) -> error: DataError,
+ (prefs: AnyCalendarPreferences) -> error: DataError,
functions: [
new_for_locale: skip,
try_new_for_locale_with_any_provider,
@@ -767,7 +781,7 @@ impl AnyCalendar {
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::new_for_locale)]
pub fn try_new_for_locale_unstable
(
provider: &P,
- locale: &DataLocale,
+ prefs: AnyCalendarPreferences,
) -> Result
where
P: DataProvider
@@ -778,7 +792,7 @@ impl AnyCalendar {
+ DataProvider
+ ?Sized,
{
- let kind = AnyCalendarKind::from_data_locale_with_fallback(locale);
+ let kind = AnyCalendarKind::from_prefs_with_fallback(prefs);
Self::try_new_unstable(provider, kind)
}
@@ -1028,6 +1042,40 @@ impl AnyCalendarKind {
}
}
+ fn get_for_preferences_calendar(pcal: CalendarAlgorithm) -> Option {
+ match pcal {
+ CalendarAlgorithm::Buddhist => Some(Self::Buddhist),
+ CalendarAlgorithm::Chinese => Some(Self::Chinese),
+ CalendarAlgorithm::Coptic => Some(Self::Coptic),
+ CalendarAlgorithm::Dangi => Some(Self::Dangi),
+ CalendarAlgorithm::Ethioaa => Some(Self::EthiopianAmeteAlem),
+ CalendarAlgorithm::Ethiopic => Some(Self::Ethiopian),
+ CalendarAlgorithm::Gregory => Some(Self::Gregorian),
+ CalendarAlgorithm::Hebrew => Some(Self::Hebrew),
+ CalendarAlgorithm::Indian => Some(Self::Indian),
+ CalendarAlgorithm::Islamic(None) => Some(Self::IslamicObservational),
+ CalendarAlgorithm::Islamic(Some(islamic)) => match islamic {
+ IslamicCalendarAlgorithm::Umalqura => Some(Self::IslamicUmmAlQura),
+ IslamicCalendarAlgorithm::Tbla => Some(Self::IslamicTabular),
+ IslamicCalendarAlgorithm::Civil => Some(Self::IslamicCivil),
+ // Rgsa is not supported
+ IslamicCalendarAlgorithm::Rgsa => None,
+ _ => {
+ debug_assert!(false, "unknown calendar algorithm {pcal:?}");
+ None
+ }
+ },
+ CalendarAlgorithm::Iso8601 => Some(Self::Iso),
+ CalendarAlgorithm::Japanese => Some(Self::Japanese),
+ CalendarAlgorithm::Persian => Some(Self::Persian),
+ CalendarAlgorithm::Roc => Some(Self::Roc),
+ _ => {
+ debug_assert!(false, "unknown calendar algorithm {pcal:?}");
+ None
+ }
+ }
+ }
+
fn debug_name(self) -> &'static str {
match self {
AnyCalendarKind::Buddhist => Buddhist.debug_name(),
@@ -1062,21 +1110,22 @@ impl AnyCalendarKind {
.and_then(Self::get_for_bcp47_value)
}
- /// Extract the calendar component from a [`DataLocale`]
+ /// Extract the calendar component from a [`AnyCalendarPreferences`]
///
/// Returns `None` if the calendar is not specified or unknown.
- fn get_for_data_locale(l: &DataLocale) -> Option {
- l.get_unicode_ext(&key!("ca"))
- .and_then(|v| Self::get_for_bcp47_value(&v))
+ fn get_for_prefs(prefs: AnyCalendarPreferences) -> Option {
+ prefs
+ .calendar_algorithm
+ .and_then(Self::get_for_preferences_calendar)
}
// Do not make public, this will eventually need fallback
// data from the provider
- fn from_data_locale_with_fallback(l: &DataLocale) -> Self {
- if let Some(kind) = Self::get_for_data_locale(l) {
+ fn from_prefs_with_fallback(prefs: AnyCalendarPreferences) -> Self {
+ if let Some(kind) = Self::get_for_prefs(prefs) {
kind
} else {
- let lang = l.language;
+ let lang = prefs.locale_prefs.language;
if lang == language!("th") {
Self::Buddhist
} else if lang == language!("sa") {
diff --git a/components/calendar/src/lib.rs b/components/calendar/src/lib.rs
index a18840f9004..dc57ea88896 100644
--- a/components/calendar/src/lib.rs
+++ b/components/calendar/src/lib.rs
@@ -200,7 +200,7 @@ pub mod week {
#[cfg(feature = "ixdtf")]
pub use crate::ixdtf::ParseError;
#[doc(no_inline)]
-pub use any_calendar::{AnyCalendar, AnyCalendarKind};
+pub use any_calendar::{AnyCalendar, AnyCalendarKind, AnyCalendarPreferences};
pub use calendar::Calendar;
pub use date::{AsCalendar, Date, Ref};
pub use datetime::DateTime;
diff --git a/components/datetime/README.md b/components/datetime/README.md
index 5d13c0b8288..e4816cdc645 100644
--- a/components/datetime/README.md
+++ b/components/datetime/README.md
@@ -60,7 +60,7 @@ let field_set = fieldsets::YMDT::medium().hm();
// Create a formatter for Argentinian Spanish:
let locale = locale!("es-AR");
-let dtf = DateTimeFormatter::try_new(&locale.into(), field_set).unwrap();
+let dtf = DateTimeFormatter::try_new(locale.into(), field_set).unwrap();
// Format something:
let datetime = DateTime::try_new_iso(2025, 1, 15, 16, 9, 35).unwrap();
diff --git a/components/datetime/benches/datetime.rs b/components/datetime/benches/datetime.rs
index 8741f35f620..dc080db339b 100644
--- a/components/datetime/benches/datetime.rs
+++ b/components/datetime/benches/datetime.rs
@@ -52,7 +52,7 @@ fn datetime_benches(c: &mut Criterion) {
let dtf = {
FixedCalendarDateTimeFormatter::::try_new(
- &locale.into(),
+ locale.into(),
skeleton,
)
.expect("Failed to create FixedCalendarDateTimeFormatter.")
diff --git a/components/datetime/examples/work_log.rs b/components/datetime/examples/work_log.rs
index 9a8f7ff6672..5f8a1564495 100644
--- a/components/datetime/examples/work_log.rs
+++ b/components/datetime/examples/work_log.rs
@@ -27,7 +27,7 @@ const DATES_ISO: &[(i32, u8, u8, u8, u8, u8)] = &[
];
fn main() {
- let dtf = FixedCalendarDateTimeFormatter::try_new(&locale!("en").into(), YMDT::medium())
+ let dtf = FixedCalendarDateTimeFormatter::try_new(locale!("en").into(), YMDT::medium())
.expect("Failed to create FixedCalendarDateTimeFormatter instance.");
println!("\n====== Work Log (en) example ============");
diff --git a/components/datetime/src/combo.rs b/components/datetime/src/combo.rs
index 98dff18245c..843bcbc94f5 100644
--- a/components/datetime/src/combo.rs
+++ b/components/datetime/src/combo.rs
@@ -34,7 +34,7 @@ use crate::{provider::neo::*, scaffold::*};
///
/// // Note: Combo type can be elided, but it is shown here for demonstration
/// let formatter = DateTimeFormatter::>::try_new(
-/// &locale!("en-US").into(),
+/// locale!("en-US").into(),
/// ET::short().hm().zone_l(),
/// )
/// .unwrap();
@@ -62,7 +62,7 @@ use crate::{provider::neo::*, scaffold::*};
///
/// // Note: Combo type can be elided, but it is shown here for demonstration
/// let formatter = FixedCalendarDateTimeFormatter::<_, Combo>::try_new(
-/// &locale!("en-US").into(),
+/// locale!("en-US").into(),
/// ET::short().hm().zone_l(),
/// )
/// .unwrap();
@@ -91,7 +91,7 @@ use crate::{provider::neo::*, scaffold::*};
///
/// // Note: Combo type can be elided, but it is shown here for demonstration
/// let formatter = DateTimeFormatter::>::try_new(
-/// &locale!("en-US").into(),
+/// locale!("en-US").into(),
/// DateFieldSet::YMD(YMD::long()).zone_v(),
/// )
/// .unwrap();
diff --git a/components/datetime/src/dynamic.rs b/components/datetime/src/dynamic.rs
index 64e9637b9a4..b423d601c40 100644
--- a/components/datetime/src/dynamic.rs
+++ b/components/datetime/src/dynamic.rs
@@ -45,11 +45,10 @@
//! }
//! }
//!
-//! let locale = locale!("en-US").into();
//! let datetime = DateTime::try_new_iso(2025, 1, 15, 16, 0, 0).unwrap();
//!
//! let results = [true, false].map(get_field_set).map(|field_set| {
-//! DateTimeFormatter::try_new(&locale, field_set).unwrap()
+//! DateTimeFormatter::try_new(locale!("en-US").into(), field_set).unwrap()
//! }).map(|formatter| {
//! formatter.convert_and_format(&datetime).try_write_to_string().unwrap().into_owned()
//! });
diff --git a/components/datetime/src/external_loaders.rs b/components/datetime/src/external_loaders.rs
index d6e213e737d..044c85b48b2 100644
--- a/components/datetime/src/external_loaders.rs
+++ b/components/datetime/src/external_loaders.rs
@@ -4,9 +4,9 @@
//! Internal traits and structs for loading data from other crates.
-use icu_calendar::AnyCalendar;
+use icu_calendar::{AnyCalendar, AnyCalendarPreferences};
use icu_decimal::options::FixedDecimalFormatterOptions;
-use icu_decimal::FixedDecimalFormatter;
+use icu_decimal::{FixedDecimalFormatter, FixedDecimalFormatterPreferences};
use icu_provider::prelude::*;
/// Trait for loading a FixedDecimalFormatter.
@@ -15,7 +15,7 @@ use icu_provider::prelude::*;
pub(crate) trait FixedDecimalFormatterLoader {
fn load(
&self,
- locale: &DataLocale,
+ prefs: FixedDecimalFormatterPreferences,
options: FixedDecimalFormatterOptions,
) -> Result;
}
@@ -24,7 +24,7 @@ pub(crate) trait FixedDecimalFormatterLoader {
///
/// Implemented on the provider-specific loader types in this module.
pub(crate) trait AnyCalendarLoader {
- fn load(&self, locale: &DataLocale) -> Result;
+ fn load(&self, prefs: AnyCalendarPreferences) -> Result;
}
/// Loader for types from other crates using compiled data.
@@ -36,19 +36,18 @@ impl FixedDecimalFormatterLoader for ExternalLoaderCompiledData {
#[inline]
fn load(
&self,
- locale: &DataLocale,
+ prefs: FixedDecimalFormatterPreferences,
options: FixedDecimalFormatterOptions,
) -> Result {
- let temp_loc = locale.clone().into_locale();
- FixedDecimalFormatter::try_new(temp_loc.into(), options)
+ FixedDecimalFormatter::try_new(prefs, options)
}
}
#[cfg(feature = "compiled_data")]
impl AnyCalendarLoader for ExternalLoaderCompiledData {
#[inline]
- fn load(&self, locale: &DataLocale) -> Result {
- Ok(AnyCalendar::new_for_locale(locale))
+ fn load(&self, prefs: AnyCalendarPreferences) -> Result {
+ Ok(AnyCalendar::new_for_locale(prefs))
}
}
@@ -62,11 +61,10 @@ where
#[inline]
fn load(
&self,
- locale: &DataLocale,
+ prefs: FixedDecimalFormatterPreferences,
options: FixedDecimalFormatterOptions,
) -> Result {
- let temp_loc = locale.clone().into_locale();
- FixedDecimalFormatter::try_new_with_any_provider(self.0, temp_loc.into(), options)
+ FixedDecimalFormatter::try_new_with_any_provider(self.0, prefs, options)
}
}
@@ -75,8 +73,8 @@ where
P: ?Sized + AnyProvider,
{
#[inline]
- fn load(&self, locale: &DataLocale) -> Result {
- AnyCalendar::try_new_for_locale_with_any_provider(self.0, locale)
+ fn load(&self, prefs: AnyCalendarPreferences) -> Result {
+ AnyCalendar::try_new_for_locale_with_any_provider(self.0, prefs)
}
}
@@ -92,11 +90,10 @@ where
#[inline]
fn load(
&self,
- locale: &DataLocale,
+ prefs: FixedDecimalFormatterPreferences,
options: FixedDecimalFormatterOptions,
) -> Result {
- let temp_loc = locale.clone().into_locale();
- FixedDecimalFormatter::try_new_with_buffer_provider(self.0, temp_loc.into(), options)
+ FixedDecimalFormatter::try_new_with_buffer_provider(self.0, prefs, options)
}
}
@@ -106,8 +103,8 @@ where
P: ?Sized + BufferProvider,
{
#[inline]
- fn load(&self, locale: &DataLocale) -> Result {
- AnyCalendar::try_new_for_locale_with_buffer_provider(self.0, locale)
+ fn load(&self, prefs: AnyCalendarPreferences) -> Result {
+ AnyCalendar::try_new_for_locale_with_buffer_provider(self.0, prefs)
}
}
@@ -123,11 +120,10 @@ where
#[inline]
fn load(
&self,
- locale: &DataLocale,
+ prefs: FixedDecimalFormatterPreferences,
options: FixedDecimalFormatterOptions,
) -> Result {
- let temp_loc = locale.clone().into_locale();
- FixedDecimalFormatter::try_new_unstable(self.0, temp_loc.into(), options)
+ FixedDecimalFormatter::try_new_unstable(self.0, prefs, options)
}
}
@@ -142,7 +138,7 @@ where
+ ?Sized,
{
#[inline]
- fn load(&self, locale: &DataLocale) -> Result {
- AnyCalendar::try_new_for_locale_unstable(self.0, locale)
+ fn load(&self, prefs: AnyCalendarPreferences) -> Result {
+ AnyCalendar::try_new_for_locale_unstable(self.0, prefs)
}
}
diff --git a/components/datetime/src/fieldsets.rs b/components/datetime/src/fieldsets.rs
index 2c45e4dd310..16ba40c0865 100644
--- a/components/datetime/src/fieldsets.rs
+++ b/components/datetime/src/fieldsets.rs
@@ -373,7 +373,7 @@ macro_rules! impl_date_or_calendar_period_marker {
/// use icu::locale::locale;
/// use writeable::assert_try_writeable_eq;
#[doc = concat!("let fmt = DateTimeFormatter::<", stringify!($type), ">::try_new(")]
- /// &locale!("en").into(),
+ /// locale!("en").into(),
#[doc = concat!(" ", length_option_helper!($type, $sample_length), ",")]
/// )
/// .unwrap();
@@ -396,7 +396,7 @@ macro_rules! impl_date_or_calendar_period_marker {
/// use writeable::assert_try_writeable_eq;
///
#[doc = concat!("let fmt = FixedCalendarDateTimeFormatter::::try_new(")]
- /// &locale!("en").into(),
+ /// locale!("en").into(),
#[doc = concat!(" ", length_option_helper!($type, $sample_length), ",")]
/// )
/// .unwrap();
@@ -519,7 +519,7 @@ macro_rules! impl_date_marker {
/// use writeable::assert_try_writeable_eq;
///
#[doc = concat!("let fmt = DateTimeFormatter::try_new(")]
- /// &locale!("en").into(),
+ /// locale!("en").into(),
#[doc = concat!(" ", length_option_helper!($type_time, $sample_length), ",")]
/// )
/// .unwrap();
@@ -542,7 +542,7 @@ macro_rules! impl_date_marker {
/// use writeable::assert_try_writeable_eq;
///
#[doc = concat!("let fmt = FixedCalendarDateTimeFormatter::try_new(")]
- /// &locale!("en").into(),
+ /// locale!("en").into(),
#[doc = concat!(" ", length_option_helper!($type_time, $sample_length), ",")]
/// )
/// .unwrap();
@@ -705,7 +705,7 @@ macro_rules! impl_time_marker {
/// use writeable::assert_try_writeable_eq;
///
#[doc = concat!("let fmt = TimeFormatter::try_new(")]
- /// &locale!("en").into(),
+ /// locale!("en").into(),
#[doc = concat!(" ", length_option_helper!($type, $sample_length), ",")]
/// )
/// .unwrap();
@@ -822,7 +822,7 @@ macro_rules! impl_zone_marker {
/// use writeable::assert_try_writeable_eq;
///
#[doc = concat!("let fmt = TimeFormatter::try_new(")]
- /// &locale!("en").into(),
+ /// locale!("en").into(),
#[doc = concat!(" ", length_option_helper!($type, $sample_length), ",")]
/// )
/// .unwrap();
@@ -914,7 +914,7 @@ macro_rules! impl_zoneddatetime_marker {
/// use writeable::assert_try_writeable_eq;
///
#[doc = concat!("let fmt = DateTimeFormatter::try_new(")]
- /// &locale!("en-GB").into(),
+ /// locale!("en-GB").into(),
#[doc = concat!(" ", length_option_helper!($type, $sample_length), ",")]
/// )
/// .unwrap();
@@ -939,7 +939,7 @@ macro_rules! impl_zoneddatetime_marker {
/// use writeable::assert_try_writeable_eq;
///
#[doc = concat!("let fmt = FixedCalendarDateTimeFormatter::::try_new(")]
- /// &locale!("en-GB").into(),
+ /// locale!("en-GB").into(),
#[doc = concat!(" ", length_option_helper!($type, $sample_length), ",")]
/// )
/// .unwrap();
@@ -1111,7 +1111,7 @@ impl_time_marker!(
/// // but we can set overrides.
///
/// let formatter = TimeFormatter::try_new(
- /// &locale!("en-US-u-hc-h12").into(),
+ /// locale!("en-US-u-hc-h12").into(),
/// T::short().hm(),
/// )
/// .unwrap();
@@ -1121,7 +1121,7 @@ impl_time_marker!(
/// );
///
/// let formatter = TimeFormatter::try_new(
- /// &locale!("en-US-u-hc-h23").into(),
+ /// locale!("en-US-u-hc-h23").into(),
/// T::short().hm(),
/// )
/// .unwrap();
@@ -1131,7 +1131,7 @@ impl_time_marker!(
/// );
///
/// let formatter = TimeFormatter::try_new(
- /// &locale!("fr-FR-u-hc-h12").into(),
+ /// locale!("fr-FR-u-hc-h12").into(),
/// T::short().hm(),
/// )
/// .unwrap();
@@ -1141,7 +1141,7 @@ impl_time_marker!(
/// );
///
/// let formatter = TimeFormatter::try_new(
- /// &locale!("fr-FR-u-hc-h23").into(),
+ /// locale!("fr-FR-u-hc-h23").into(),
/// T::short().hm(),
/// )
/// .unwrap();
@@ -1161,7 +1161,7 @@ impl_time_marker!(
/// use writeable::assert_try_writeable_eq;
///
/// let formatter = TimeFormatter::try_new(
- /// &locale!("und-u-hc-h11").into(),
+ /// locale!("und-u-hc-h11").into(),
/// T::short().hm(),
/// )
/// .unwrap();
@@ -1172,7 +1172,7 @@ impl_time_marker!(
/// );
///
/// let formatter = TimeFormatter::try_new(
- /// &locale!("und-u-hc-h24").into(),
+ /// locale!("und-u-hc-h24").into(),
/// T::short().hm(),
/// )
/// .unwrap();
@@ -1214,7 +1214,7 @@ impl_zone_marker!(
/// .with_zone_variant(ZoneVariant::Standard);
///
/// let fmt = FixedCalendarDateTimeFormatter::::try_new(
- /// &locale!("en").into(),
+ /// locale!("en").into(),
/// Z::short(),
/// )
/// .unwrap();
@@ -1225,7 +1225,7 @@ impl_zone_marker!(
/// );
///
/// let fmt = FixedCalendarDateTimeFormatter::::try_new(
- /// &locale!("en").into(),
+ /// locale!("en").into(),
/// Z::long(),
/// )
/// .unwrap();
@@ -1254,7 +1254,7 @@ impl_zone_marker!(
/// let time_zone_at_time = time_zone_basic.at_time((datetime.date.to_iso(), datetime.time));
///
/// let formatter = FixedCalendarDateTimeFormatter::try_new(
- /// &locale!("en-US").into(),
+ /// locale!("en-US").into(),
/// Z::medium(),
/// )
/// .unwrap();
@@ -1299,7 +1299,7 @@ impl_zone_marker!(
/// let time_zone_at_time = time_zone_basic.at_time((datetime.date.to_iso(), datetime.time));
///
/// let formatter = FixedCalendarDateTimeFormatter::try_new(
- /// &locale!("en-US").into(),
+ /// locale!("en-US").into(),
/// Combo::::medium(),
/// )
/// .unwrap();
@@ -1346,7 +1346,7 @@ impl_zone_marker!(
/// let time_zone_full = time_zone_at_time.with_zone_variant(ZoneVariant::Standard);
///
/// let formatter = TimeFormatter::try_new(
- /// &locale!("en-US").into(),
+ /// locale!("en-US").into(),
/// O::medium(),
/// )
/// .unwrap();
@@ -1401,7 +1401,7 @@ impl_zone_marker!(
/// .at_time((Date::try_new_iso(2022, 1, 29).unwrap(), Time::midnight()));
///
/// let fmt = FixedCalendarDateTimeFormatter::::try_new(
- /// &locale!("en").into(),
+ /// locale!("en").into(),
/// V::short(),
/// )
/// .unwrap();
@@ -1426,7 +1426,7 @@ impl_zone_marker!(
///
/// // Set up the formatter
/// let mut tzf = TimeFormatter::try_new(
- /// &locale!("en").into(),
+ /// locale!("en").into(),
/// V::short(),
/// )
/// .unwrap();
@@ -1477,7 +1477,7 @@ impl_zone_marker!(
/// let time_zone_basic = TimeZoneBcp47Id(tinystr!(8, "uschi")).without_offset();
///
/// let formatter = TimeFormatter::try_new(
- /// &locale!("en-US").into(),
+ /// locale!("en-US").into(),
/// V::medium(),
/// )
/// .unwrap();
@@ -1519,7 +1519,7 @@ impl_zone_marker!(
/// let time_zone_basic = TimeZoneBcp47Id(tinystr!(8, "uschi")).with_offset("-06".parse().ok());1
///
/// let formatter = FixedCalendarDateTimeFormatter::try_new(
- /// &locale!("en-US").into(),
+ /// locale!("en-US").into(),
/// Vs::medium(),
/// )
/// .unwrap();
@@ -1560,7 +1560,7 @@ impl_zone_marker!(
/// let utc_offset = UtcOffset::try_from_str("-06").unwrap();
///
/// let formatter = FixedCalendarDateTimeFormatter::try_new(
- /// &locale!("en-US").into(),
+ /// locale!("en-US").into(),
/// L::medium(),
/// )
/// .unwrap();
diff --git a/components/datetime/src/lib.rs b/components/datetime/src/lib.rs
index ba27e83cbcd..ba14bec7252 100644
--- a/components/datetime/src/lib.rs
+++ b/components/datetime/src/lib.rs
@@ -60,7 +60,7 @@
//!
//! // Create a formatter for Argentinian Spanish:
//! let locale = locale!("es-AR");
-//! let dtf = DateTimeFormatter::try_new(&locale.into(), field_set).unwrap();
+//! let dtf = DateTimeFormatter::try_new(locale.into(), field_set).unwrap();
//!
//! // Format something:
//! let datetime = DateTime::try_new_iso(2025, 1, 15, 16, 9, 35).unwrap();
@@ -108,6 +108,7 @@ pub(crate) mod size_test_macro;
pub use error::{DateTimeFormatterLoadError, DateTimeWriteError, MismatchedCalendarError};
pub use neo::DateTimeFormatter;
+pub use neo::DateTimeFormatterPreferences;
pub use neo::FixedCalendarDateTimeFormatter;
pub use neo::FormattedDateTime;
pub use neo::TimeFormatter;
diff --git a/components/datetime/src/neo.rs b/components/datetime/src/neo.rs
index 56c079b496c..6fdf826e40e 100644
--- a/components/datetime/src/neo.rs
+++ b/components/datetime/src/neo.rs
@@ -22,18 +22,46 @@ use crate::MismatchedCalendarError;
use core::fmt;
use core::marker::PhantomData;
use icu_calendar::any_calendar::IntoAnyCalendar;
-use icu_calendar::AnyCalendar;
-use icu_locale_core::preferences::extensions::unicode::keywords::HourCycle;
+use icu_calendar::{AnyCalendar, AnyCalendarPreferences};
+use icu_decimal::FixedDecimalFormatterPreferences;
+use icu_locale_core::preferences::extensions::unicode::keywords::{
+ CalendarAlgorithm, HourCycle, NumberingSystem,
+};
+use icu_locale_core::preferences::{define_preferences, prefs_convert};
use icu_provider::prelude::*;
use writeable::TryWriteable;
+define_preferences!(
+ /// The prefs for datetime formatting.
+ [Copy]
+ DateTimeFormatterPreferences,
+ {
+ /// The user's preferred numbering system
+ numbering_system: NumberingSystem,
+ /// The user's preferred hour cycle
+ hour_cycle: HourCycle,
+ /// The user's preferred calendar system
+ calendar_algorithm: CalendarAlgorithm
+ }
+);
+
+prefs_convert!(
+ DateTimeFormatterPreferences,
+ FixedDecimalFormatterPreferences,
+ { numbering_system }
+);
+
+prefs_convert!(DateTimeFormatterPreferences, AnyCalendarPreferences, {
+ calendar_algorithm
+});
+
/// Helper macro for generating any/buffer constructors in this file.
macro_rules! gen_any_buffer_constructors_with_external_loader {
(@runtime_fset, $fset:ident, $compiled_fn:ident, $any_fn:ident, $buffer_fn:ident, $internal_fn:ident) => {
#[doc = icu_provider::gen_any_buffer_unstable_docs!(ANY, Self::$compiled_fn)]
pub fn $any_fn(
provider: &P,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
field_set: $fset,
) -> Result
where
@@ -42,7 +70,7 @@ macro_rules! gen_any_buffer_constructors_with_external_loader {
Self::$internal_fn(
&provider.as_downcasting(),
&ExternalLoaderAny(provider),
- locale,
+ prefs,
field_set.get_field(),
)
}
@@ -50,7 +78,7 @@ macro_rules! gen_any_buffer_constructors_with_external_loader {
#[cfg(feature = "serde")]
pub fn $buffer_fn(
provider: &P,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
field_set: $fset,
) -> Result
where
@@ -59,7 +87,7 @@ macro_rules! gen_any_buffer_constructors_with_external_loader {
Self::$internal_fn(
&provider.as_deserializing(),
&ExternalLoaderBuffer(provider),
- locale,
+ prefs,
field_set.get_field(),
)
}
@@ -68,7 +96,7 @@ macro_rules! gen_any_buffer_constructors_with_external_loader {
#[doc = icu_provider::gen_any_buffer_unstable_docs!(ANY, Self::$compiled_fn)]
pub fn $any_fn(
provider: &P,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
field_set: $fset,
) -> Result
where
@@ -77,7 +105,7 @@ macro_rules! gen_any_buffer_constructors_with_external_loader {
Self::$internal_fn(
&provider.as_downcasting(),
&ExternalLoaderAny(provider),
- locale,
+ prefs,
field_set.get_field(),
)
}
@@ -85,7 +113,7 @@ macro_rules! gen_any_buffer_constructors_with_external_loader {
#[cfg(feature = "serde")]
pub fn $buffer_fn(
provider: &P,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
field_set: $fset,
) -> Result
where
@@ -94,44 +122,13 @@ macro_rules! gen_any_buffer_constructors_with_external_loader {
Self::$internal_fn(
&provider.as_deserializing(),
&ExternalLoaderBuffer(provider),
- locale,
+ prefs,
field_set.get_field(),
)
}
};
}
-// impl RawOptions {
-// pub(crate) fn from_field_set_and_locale(field_set: &FSet, locale: &DataLocale) -> Self
-// where
-// FSet: DateTimeMarkers,
-// FSet: GetField,
-// FSet: GetField,
-// FSet: GetField,
-// FSet: GetField,
-// {
-// // TODO: Return an error if there are more options than field set
-// let hour_cycle = locale
-// .get_unicode_ext(&icu_locale_core::extensions::unicode::key!("hc"))
-// .as_ref()
-// .and_then(HourCycle::from_locale_value);
-// Self {
-// length: match GetField::::get_field(field_set).into_option() {
-// Some(length) => length,
-// None => {
-// debug_assert!(false, "unreachable");
-// NeoSkeletonLength::Medium
-// }
-// },
-// alignment: GetField::::get_field(field_set).into_option(),
-// year_style: GetField::::get_field(field_set).into_option(),
-// time_precision: GetField::::get_field(field_set)
-// .into_option(),
-// hour_cycle,
-// }
-// }
-// }
-
size_test!(FixedCalendarDateTimeFormatter, typed_neo_year_month_day_formatter_size, 344);
/// [`FixedCalendarDateTimeFormatter`] is a formatter capable of formatting dates and/or times from
@@ -175,7 +172,7 @@ where
/// use writeable::assert_try_writeable_eq;
///
/// let formatter = FixedCalendarDateTimeFormatter::try_new(
- /// &locale!("es-MX").into(),
+ /// locale!("es-MX").into(),
/// YMD::long(),
/// )
/// .unwrap();
@@ -186,14 +183,17 @@ where
/// );
/// ```
#[cfg(feature = "compiled_data")]
- pub fn try_new(locale: &DataLocale, field_set: FSet) -> Result
+ pub fn try_new(
+ prefs: DateTimeFormatterPreferences,
+ field_set: FSet,
+ ) -> Result
where
crate::provider::Baked: AllFixedCalendarFormattingDataMarkers,
{
Self::try_new_internal(
&crate::provider::Baked,
&ExternalLoaderCompiledData,
- locale,
+ prefs,
field_set.get_field(),
)
}
@@ -210,7 +210,7 @@ where
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
pub fn try_new_unstable(
provider: &P,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
field_set: FSet,
) -> Result
where
@@ -221,7 +221,7 @@ where
Self::try_new_internal(
provider,
&ExternalLoaderUnstable(provider),
- locale,
+ prefs,
field_set.get_field(),
)
}
@@ -236,30 +236,19 @@ where
fn try_new_internal(
provider: &P,
loader: &L,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
field_set: CompositeFieldSet,
) -> Result
where
P: ?Sized + AllFixedCalendarFormattingDataMarkers,
L: FixedDecimalFormatterLoader,
{
- // TODO: Fix this when we have DateTimePreferences
- let prefs = RawPreferences {
- hour_cycle: locale
- .get_unicode_ext(&icu_locale_core::extensions::unicode::key!("hc"))
- .as_ref()
- .and_then(|v| HourCycle::try_from(v).ok())
- .map(crate::fields::Hour::from_hour_cycle),
- };
- // END TODO
-
let selection = DateTimeZonePatternSelectionData::try_new_with_skeleton(
&>::DateSkeletonPatternsV1Marker::bind(provider),
&::TimeSkeletonPatternsV1Marker::bind(provider),
&FSet::GluePatternV1Marker::bind(provider),
- locale,
- field_set,
prefs,
+ field_set,
)
.map_err(DateTimeFormatterLoadError::Data)?;
let mut names = RawDateTimeNames::new_without_number_formatting();
@@ -277,7 +266,7 @@ where
&::SpecificShortV1Marker::bind(provider),
&::MetazonePeriodV1Marker::bind(provider),
loader, // fixed decimal formatter
- locale,
+ prefs,
selection.pattern_items_for_data_loading(),
)
.map_err(DateTimeFormatterLoadError::Names)?;
@@ -310,7 +299,7 @@ where
///
/// let formatter =
/// FixedCalendarDateTimeFormatter::::try_new(
- /// &locale!("es-MX").into(),
+ /// locale!("es-MX").into(),
/// YMD::long(),
/// )
/// .unwrap();
@@ -330,7 +319,7 @@ where
///
/// let formatter =
/// FixedCalendarDateTimeFormatter::::try_new(
- /// &locale!("es-MX").into(),
+ /// locale!("es-MX").into(),
/// YMD::long(),
/// )
/// .unwrap();
@@ -405,10 +394,8 @@ where
/// use std::str::FromStr;
/// use writeable::assert_try_writeable_eq;
///
- /// let locale = locale!("en-u-ca-hebrew");
- ///
/// let formatter =
- /// DateTimeFormatter::try_new(&locale.into(), YMD::medium()).unwrap();
+ /// DateTimeFormatter::try_new(locale!("en-u-ca-hebrew").into(), YMD::medium()).unwrap();
///
/// let datetime = DateTime::try_new_iso(2024, 5, 8, 0, 0, 0).unwrap();
///
@@ -421,14 +408,17 @@ where
/// [`AnyCalendarKind`]: icu_calendar::AnyCalendarKind
#[inline(never)]
#[cfg(feature = "compiled_data")]
- pub fn try_new(locale: &DataLocale, field_set: FSet) -> Result
+ pub fn try_new(
+ prefs: DateTimeFormatterPreferences,
+ field_set: FSet,
+ ) -> Result
where
crate::provider::Baked: AllAnyCalendarFormattingDataMarkers,
{
Self::try_new_internal(
&crate::provider::Baked,
&ExternalLoaderCompiledData,
- locale,
+ prefs,
field_set.get_field(),
)
}
@@ -445,7 +435,7 @@ where
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
pub fn try_new_unstable(
provider: &P,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
field_set: FSet,
) -> Result
where
@@ -454,7 +444,7 @@ where
Self::try_new_internal(
provider,
&ExternalLoaderUnstable(provider),
- locale,
+ prefs,
field_set.get_field(),
)
}
@@ -469,33 +459,22 @@ where
fn try_new_internal(
provider: &P,
loader: &L,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
field_set: CompositeFieldSet,
) -> Result
where
P: ?Sized + AllAnyCalendarFormattingDataMarkers,
L: FixedDecimalFormatterLoader + AnyCalendarLoader,
{
- // TODO: Fix this when we have DateTimePreferences
- let prefs = RawPreferences {
- hour_cycle: locale
- .get_unicode_ext(&icu_locale_core::extensions::unicode::key!("hc"))
- .as_ref()
- .and_then(|v| HourCycle::try_from(v).ok())
- .map(crate::fields::Hour::from_hour_cycle),
- };
- // END TODO
-
- let calendar =
- AnyCalendarLoader::load(loader, locale).map_err(DateTimeFormatterLoadError::Data)?;
+ let calendar = AnyCalendarLoader::load(loader, (&prefs).into())
+ .map_err(DateTimeFormatterLoadError::Data)?;
let kind = calendar.kind();
let selection = DateTimeZonePatternSelectionData::try_new_with_skeleton(
&AnyCalendarProvider::<::Skel, _>::new(provider, kind),
&::TimeSkeletonPatternsV1Marker::bind(provider),
&FSet::GluePatternV1Marker::bind(provider),
- locale,
- field_set,
prefs,
+ field_set,
)
.map_err(DateTimeFormatterLoadError::Data)?;
let mut names = RawDateTimeNames::new_without_number_formatting();
@@ -513,7 +492,7 @@ where
&::SpecificShortV1Marker::bind(provider),
&::MetazonePeriodV1Marker::bind(provider),
loader, // fixed decimal formatter
- locale,
+ prefs,
selection.pattern_items_for_data_loading(),
)
.map_err(DateTimeFormatterLoadError::Names)?;
@@ -548,7 +527,7 @@ where
/// use icu::locale::locale;
///
/// let formatter = DateTimeFormatter::try_new(
- /// &locale!("en-u-ca-hebrew").into(),
+ /// locale!("en-u-ca-hebrew").into(),
/// YMD::long(),
/// )
/// .unwrap();
@@ -570,7 +549,7 @@ where
/// use icu::locale::locale;
///
/// let formatter = DateTimeFormatter::try_new(
- /// &locale!("es-MX").into(),
+ /// locale!("es-MX").into(),
/// NeoSkeletonLength::Long.into(),
/// )
/// .unwrap();
@@ -612,7 +591,7 @@ where
/// use writeable::assert_try_writeable_eq;
///
/// let formatter = DateTimeFormatter::try_new(
- /// &locale!("en-u-ca-hebrew").into(),
+ /// locale!("en-u-ca-hebrew").into(),
/// YMD::long(),
/// )
/// .unwrap();
@@ -634,7 +613,7 @@ where
/// use icu::locale::locale;
///
/// let formatter = DateTimeFormatter::try_new(
- /// &locale!("es-MX").into(),
+ /// locale!("es-MX").into(),
/// NeoSkeletonLength::Long.into(),
/// )
/// .unwrap();
@@ -678,7 +657,7 @@ impl FixedCalendarDateTimeFormatter DateTimeFormatter {
/// use writeable::assert_try_writeable_eq;
///
/// let formatter = DateTimeFormatter::try_new(
- /// &locale!("en-u-ca-hebrew").into(),
+ /// locale!("en-u-ca-hebrew").into(),
/// YMD::long(),
/// )
/// .unwrap()
@@ -742,7 +721,7 @@ impl DateTimeFormatter {
/// use icu::locale::locale;
///
/// let result = DateTimeFormatter::try_new(
- /// &locale!("en-u-ca-buddhist").into(),
+ /// locale!("en-u-ca-buddhist").into(),
/// YMD::long(),
/// )
/// .unwrap()
@@ -781,7 +760,7 @@ impl DateTimeFormatter {
/// use icu::datetime::fieldsets::Y;
/// use icu::locale::locale;
///
-/// assert!(TimeFormatter::try_new(&locale!("und").into(), Y::medium()).is_err());
+/// assert!(TimeFormatter::try_new(locale!("und").into(), Y::medium()).is_err());
/// ```
///
/// Furthermore, it is a compile error in the format function:
@@ -792,7 +771,7 @@ impl DateTimeFormatter {
/// use icu::locale::locale;
///
/// let date: icu::calendar::Date = unimplemented!();
-/// let formatter = TimeFormatter::try_new(&locale!("und").into(), Y::medium()).unwrap();
+/// let formatter = TimeFormatter::try_new(locale!("und").into(), Y::medium()).unwrap();
///
/// // error[E0271]: type mismatch resolving `::Calendar == ()`
/// formatter.format(&date);
diff --git a/components/datetime/src/options/mod.rs b/components/datetime/src/options/mod.rs
index 6fe5c1f11ec..e4408fba033 100644
--- a/components/datetime/src/options/mod.rs
+++ b/components/datetime/src/options/mod.rs
@@ -27,21 +27,21 @@ use crate::neo_serde::TimePrecisionSerde;
///
/// let short_formatter =
/// FixedCalendarDateTimeFormatter::try_new(
-/// &locale!("en-US").into(),
+/// locale!("en-US").into(),
/// YMD::short(),
/// )
/// .unwrap();
///
/// let medium_formatter =
/// FixedCalendarDateTimeFormatter::try_new(
-/// &locale!("en-US").into(),
+/// locale!("en-US").into(),
/// YMD::medium(),
/// )
/// .unwrap();
///
/// let long_formatter =
/// FixedCalendarDateTimeFormatter::try_new(
-/// &locale!("en-US").into(),
+/// locale!("en-US").into(),
/// YMD::long(),
/// )
/// .unwrap();
@@ -107,14 +107,14 @@ impl IntoOption for NeoSkeletonLength {
///
/// let plain_formatter =
/// FixedCalendarDateTimeFormatter::::try_new(
-/// &locale!("en-US").into(),
+/// locale!("en-US").into(),
/// YMD::short(),
/// )
/// .unwrap();
///
/// let column_formatter =
/// FixedCalendarDateTimeFormatter::::try_new(
-/// &locale!("en-US").into(),
+/// locale!("en-US").into(),
/// YMD::short().with_alignment(Alignment::Column),
/// )
/// .unwrap();
@@ -180,7 +180,7 @@ impl IntoOption for Alignment {
/// use writeable::assert_try_writeable_eq;
///
/// let formatter = FixedCalendarDateTimeFormatter::::try_new(
-/// &locale!("en-US").into(),
+/// locale!("en-US").into(),
/// YMD::short().with_year_style(YearStyle::Auto),
/// )
/// .unwrap();
@@ -207,7 +207,7 @@ impl IntoOption for Alignment {
/// );
///
/// let formatter = FixedCalendarDateTimeFormatter::::try_new(
-/// &locale!("en-US").into(),
+/// locale!("en-US").into(),
/// YMD::short().with_year_style(YearStyle::Full),
/// )
/// .unwrap();
@@ -233,7 +233,7 @@ impl IntoOption for Alignment {
/// );
///
/// let formatter = FixedCalendarDateTimeFormatter::::try_new(
-/// &locale!("en-US").into(),
+/// locale!("en-US").into(),
/// YMD::short().with_year_style(YearStyle::Always),
/// )
/// .unwrap();
@@ -340,7 +340,7 @@ impl IntoOption for YearStyle {
/// TimePrecision::SecondExact(FractionalSecondDigits::F0),
/// ].map(|time_precision| {
/// FixedCalendarDateTimeFormatter::<(), _>::try_new(
-/// &locale!("en-US").into(),
+/// locale!("en-US").into(),
/// T::short().with_time_precision(time_precision),
/// )
/// .unwrap()
@@ -467,7 +467,7 @@ impl IntoOption for TimePrecision {
/// use writeable::assert_try_writeable_eq;
///
/// let formatter = FixedCalendarDateTimeFormatter::<(), _>::try_new(
-/// &locale!("en-US").into(),
+/// locale!("en-US").into(),
/// T::short().with_time_precision(TimePrecision::SecondExact(FractionalSecondDigits::F2)),
/// )
/// .unwrap();
diff --git a/components/datetime/src/pattern/formatter.rs b/components/datetime/src/pattern/formatter.rs
index 61bea4ce456..7e9c06ba155 100644
--- a/components/datetime/src/pattern/formatter.rs
+++ b/components/datetime/src/pattern/formatter.rs
@@ -78,7 +78,7 @@ where
///
/// // Create an instance that can format wide month and era names:
/// let mut names: TypedDateTimeNames =
- /// TypedDateTimeNames::try_new(&locale!("en-GB").into()).unwrap();
+ /// TypedDateTimeNames::try_new(locale!("en-GB").into()).unwrap();
/// names
/// .include_month_names(fields::Month::Format, FieldLength::Four)
/// .unwrap()
@@ -117,7 +117,7 @@ where
///
/// // Create an instance that can format abbreviated day periods:
/// let mut names: TypedDateTimeNames =
- /// TypedDateTimeNames::try_new(&locale!("en-US").into()).unwrap();
+ /// TypedDateTimeNames::try_new(locale!("en-US").into()).unwrap();
/// names
/// .include_day_period_names(FieldLength::Three)
/// .unwrap();
@@ -173,7 +173,7 @@ where
///
/// let mut names =
/// TypedDateTimeNames::::try_new(
- /// &locale!("en-GB").into(),
+ /// locale!("en-GB").into(),
/// )
/// .unwrap();
///
@@ -244,8 +244,7 @@ mod tests {
#[test]
fn test_basic_pattern_formatting() {
let locale = locale!("en").into();
- let mut names: TypedDateTimeNames =
- TypedDateTimeNames::try_new(&locale).unwrap();
+ let mut names: TypedDateTimeNames = TypedDateTimeNames::try_new(locale).unwrap();
names
.load_month_names(
&crate::provider::Baked,
@@ -319,7 +318,7 @@ mod tests {
expected,
} = cas;
let mut names: TypedDateTimeNames =
- TypedDateTimeNames::try_new(&locale).unwrap();
+ TypedDateTimeNames::try_new(locale).unwrap();
names
.load_year_names(&crate::provider::Baked, field_length)
.unwrap();
@@ -390,7 +389,7 @@ mod tests {
expected,
} = cas;
let mut names: TypedDateTimeNames =
- TypedDateTimeNames::try_new(&locale).unwrap();
+ TypedDateTimeNames::try_new(locale).unwrap();
names
.load_month_names(&crate::provider::Baked, field_symbol, field_length)
.unwrap();
@@ -508,7 +507,7 @@ mod tests {
expected,
} = cas;
let mut names: TypedDateTimeNames =
- TypedDateTimeNames::try_new(&locale).unwrap();
+ TypedDateTimeNames::try_new(locale).unwrap();
names
.load_weekday_names(&crate::provider::Baked, field_symbol, field_length)
.unwrap();
@@ -590,7 +589,7 @@ mod tests {
expected,
} = cas;
let mut names: TypedDateTimeNames =
- TypedDateTimeNames::try_new(&locale).unwrap();
+ TypedDateTimeNames::try_new(locale).unwrap();
names
.load_day_period_names(&crate::provider::Baked, field_length)
.unwrap();
diff --git a/components/datetime/src/pattern/names.rs b/components/datetime/src/pattern/names.rs
index 006b831b421..416dd016cd3 100644
--- a/components/datetime/src/pattern/names.rs
+++ b/components/datetime/src/pattern/names.rs
@@ -7,7 +7,6 @@ use super::{
GetNameForWeekdayError, GetSymbolForCyclicYearError, GetSymbolForEraError,
MonthPlaceholderValue, PatternLoadError,
};
-use crate::external_loaders::*;
use crate::fields::{self, FieldLength, FieldSymbol};
use crate::fieldsets::enums::CompositeDateTimeFieldSet;
use crate::input;
@@ -16,6 +15,7 @@ use crate::provider::pattern::PatternItem;
use crate::provider::time_zones::tz;
use crate::scaffold::*;
use crate::size_test_macro::size_test;
+use crate::{external_loaders::*, DateTimeFormatterPreferences};
use core::fmt;
use core::marker::PhantomData;
use core::num::NonZeroU8;
@@ -41,7 +41,7 @@ where
size_test!(
TypedDateTimeNames,
typed_date_time_names_size,
- 344
+ 328
);
/// A low-level type that formats datetime patterns with localized names.
@@ -77,7 +77,7 @@ size_test!(
///
/// // Create an instance that can format abbreviated month, weekday, and day period names:
/// let mut names: TypedDateTimeNames =
-/// TypedDateTimeNames::try_new(&locale!("uk").into()).unwrap();
+/// TypedDateTimeNames::try_new(locale!("uk").into()).unwrap();
/// names
/// .include_month_names(fields::Month::Format, FieldLength::Three)
/// .unwrap()
@@ -112,7 +112,7 @@ size_test!(
///
/// // Create an instance that can format all fields (CompositeFieldSet):
/// let mut names: TypedDateTimeNames =
-/// TypedDateTimeNames::try_new(&locale!("en").into()).unwrap();
+/// TypedDateTimeNames::try_new(locale!("en").into()).unwrap();
///
/// // Create a pattern from a pattern string:
/// let pattern_str = "'It is:' E MMM d y G 'at' h:mm:ssSSS a zzzz";
@@ -161,7 +161,7 @@ size_test!(
///
/// // Create an instance that can format abbreviated month, weekday, and day period names:
/// let mut names: TypedDateTimeNames =
-/// TypedDateTimeNames::try_new(&locale!("en").into()).unwrap();
+/// TypedDateTimeNames::try_new(locale!("en").into()).unwrap();
///
/// // Create a pattern from a pattern string:
/// let pattern_str = "'It is:' E MMM d y G 'at' h:mm:ssSSS a zzzz";
@@ -194,7 +194,7 @@ pub struct TypedDateTimeNames<
C: CldrCalendar,
FSet: DateTimeNamesMarker = CompositeDateTimeFieldSet,
> {
- locale: DataLocale,
+ prefs: DateTimeFormatterPreferences,
inner: RawDateTimeNames,
_calendar: PhantomData,
}
@@ -285,9 +285,9 @@ impl TypedDateTimeNames {
///
/// [📚 Help choosing a constructor](icu_provider::constructors)
#[cfg(feature = "compiled_data")]
- pub fn try_new(locale: &DataLocale) -> Result {
+ pub fn try_new(prefs: DateTimeFormatterPreferences) -> Result {
let mut names = Self {
- locale: locale.clone(),
+ prefs,
inner: RawDateTimeNames::new_without_number_formatting(),
_calendar: PhantomData,
};
@@ -296,12 +296,15 @@ impl TypedDateTimeNames {
}
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
- pub fn try_new_unstable(provider: &P, locale: &DataLocale) -> Result
+ pub fn try_new_unstable(
+ provider: &P,
+ prefs: DateTimeFormatterPreferences,
+ ) -> Result
where
P: DataProvider + DataProvider + ?Sized,
{
let mut names = Self {
- locale: locale.clone(),
+ prefs,
inner: RawDateTimeNames::new_without_number_formatting(),
_calendar: PhantomData,
};
@@ -328,7 +331,7 @@ impl TypedDateTimeNames {
///
/// // Create an instance that can format only date fields:
/// let names: TypedDateTimeNames =
- /// TypedDateTimeNames::new_without_number_formatting(&locale!("en").into());
+ /// TypedDateTimeNames::new_without_number_formatting(locale!("en").into());
///
/// // Create a pattern from a pattern string:
/// let pattern_str = "'It is:' y-MM-dd";
@@ -352,9 +355,9 @@ impl TypedDateTimeNames {
/// ]
/// );
/// ```
- pub fn new_without_number_formatting(locale: &DataLocale) -> Self {
+ pub fn new_without_number_formatting(prefs: DateTimeFormatterPreferences) -> Self {
Self {
- locale: locale.clone(),
+ prefs,
inner: RawDateTimeNames::new_without_number_formatting(),
_calendar: PhantomData,
}
@@ -373,7 +376,7 @@ impl TypedDateTimeNames {
{
self.inner.load_year_names(
&C::YearNamesV1Marker::bind(provider),
- &self.locale,
+ self.prefs,
field_length,
)?;
Ok(self)
@@ -393,7 +396,7 @@ impl TypedDateTimeNames {
/// use icu::locale::locale;
///
/// let mut names =
- /// TypedDateTimeNames::::try_new(&locale!("und").into())
+ /// TypedDateTimeNames::::try_new(locale!("und").into())
/// .unwrap();
///
/// // First length is successful:
@@ -433,7 +436,7 @@ impl TypedDateTimeNames {
{
self.inner.load_month_names(
&C::MonthNamesV1Marker::bind(provider),
- &self.locale,
+ self.prefs,
field_symbol,
field_length,
)?;
@@ -454,7 +457,7 @@ impl TypedDateTimeNames {
/// use icu::locale::locale;
///
/// let mut names =
- /// TypedDateTimeNames::::try_new(&locale!("und").into())
+ /// TypedDateTimeNames::::try_new(locale!("und").into())
/// .unwrap();
/// let field_symbol = icu::datetime::fields::Month::Format;
/// let alt_field_symbol = icu::datetime::fields::Month::StandAlone;
@@ -504,7 +507,7 @@ impl TypedDateTimeNames {
{
let provider = DayPeriodNamesV1Marker::bind(provider);
self.inner
- .load_day_period_names(&provider, &self.locale, field_length)?;
+ .load_day_period_names(&provider, self.prefs, field_length)?;
Ok(self)
}
@@ -522,7 +525,7 @@ impl TypedDateTimeNames {
/// use icu::locale::locale;
///
/// let mut names =
- /// TypedDateTimeNames::::try_new(&locale!("und").into())
+ /// TypedDateTimeNames::::try_new(locale!("und").into())
/// .unwrap();
///
/// // First length is successful:
@@ -562,7 +565,7 @@ impl TypedDateTimeNames {
{
self.inner.load_weekday_names(
&WeekdayNamesV1Marker::bind(provider),
- &self.locale,
+ self.prefs,
field_symbol,
field_length,
)?;
@@ -583,7 +586,7 @@ impl TypedDateTimeNames {
/// use icu::locale::locale;
///
/// let mut names =
- /// TypedDateTimeNames::::try_new(&locale!("und").into())
+ /// TypedDateTimeNames::::try_new(locale!("und").into())
/// .unwrap();
/// let field_symbol = icu::datetime::fields::Weekday::Format;
/// let alt_field_symbol = icu::datetime::fields::Weekday::StandAlone;
@@ -629,7 +632,7 @@ impl TypedDateTimeNames {
P: DataProvider + ?Sized,
{
self.inner
- .load_time_zone_essentials(&tz::EssentialsV1Marker::bind(provider), &self.locale)?;
+ .load_time_zone_essentials(&tz::EssentialsV1Marker::bind(provider), self.prefs)?;
Ok(self)
}
@@ -662,7 +665,7 @@ impl TypedDateTimeNames {
///
/// let mut names =
/// TypedDateTimeNames::::try_new(
- /// &locale!("en-GB").into(),
+ /// locale!("en-GB").into(),
/// )
/// .unwrap();
///
@@ -729,7 +732,7 @@ impl TypedDateTimeNames {
P: DataProvider + ?Sized,
{
self.inner
- .load_time_zone_location_names(&tz::LocationsV1Marker::bind(provider), &self.locale)?;
+ .load_time_zone_location_names(&tz::LocationsV1Marker::bind(provider), self.prefs)?;
Ok(self)
}
@@ -760,7 +763,7 @@ impl TypedDateTimeNames {
///
/// let mut names =
/// TypedDateTimeNames::::try_new(
- /// &locale!("en-GB").into(),
+ /// locale!("en-GB").into(),
/// )
/// .unwrap();
///
@@ -795,7 +798,7 @@ impl TypedDateTimeNames {
self.inner.load_time_zone_generic_long_names(
&tz::MzGenericLongV1Marker::bind(provider),
&tz::MzPeriodV1Marker::bind(provider),
- &self.locale,
+ self.prefs,
)?;
Ok(self)
}
@@ -832,7 +835,7 @@ impl TypedDateTimeNames {
///
/// let mut names =
/// TypedDateTimeNames::::try_new(
- /// &locale!("en-GB").into(),
+ /// locale!("en-GB").into(),
/// )
/// .unwrap();
///
@@ -871,7 +874,7 @@ impl TypedDateTimeNames {
self.inner.load_time_zone_generic_short_names(
&tz::MzGenericShortV1Marker::bind(provider),
&tz::MzPeriodV1Marker::bind(provider),
- &self.locale,
+ self.prefs,
)?;
Ok(self)
}
@@ -908,7 +911,7 @@ impl TypedDateTimeNames {
///
/// let mut names =
/// TypedDateTimeNames::::try_new(
- /// &locale!("en-GB").into(),
+ /// locale!("en-GB").into(),
/// )
/// .unwrap();
///
@@ -947,7 +950,7 @@ impl TypedDateTimeNames {
self.inner.load_time_zone_specific_long_names(
&tz::MzSpecificLongV1Marker::bind(provider),
&tz::MzPeriodV1Marker::bind(provider),
- &self.locale,
+ self.prefs,
)?;
Ok(self)
}
@@ -984,7 +987,7 @@ impl TypedDateTimeNames {
///
/// let mut names =
/// TypedDateTimeNames::::try_new(
- /// &locale!("en-GB").into(),
+ /// locale!("en-GB").into(),
/// )
/// .unwrap();
///
@@ -1023,7 +1026,7 @@ impl TypedDateTimeNames {
self.inner.load_time_zone_specific_short_names(
&tz::MzSpecificShortV1Marker::bind(provider),
&tz::MzPeriodV1Marker::bind(provider),
- &self.locale,
+ self.prefs,
)?;
Ok(self)
}
@@ -1060,7 +1063,7 @@ impl TypedDateTimeNames {
///
/// let mut names =
/// TypedDateTimeNames::::try_new(
- /// &locale!("en-GB").into(),
+ /// locale!("en-GB").into(),
/// )
/// .unwrap();
///
@@ -1095,7 +1098,7 @@ impl TypedDateTimeNames {
P: DataProvider + DataProvider + ?Sized,
{
self.inner
- .load_fixed_decimal_formatter(&ExternalLoaderUnstable(provider), &self.locale)?;
+ .load_fixed_decimal_formatter(&ExternalLoaderUnstable(provider), self.prefs)?;
Ok(self)
}
@@ -1111,10 +1114,8 @@ impl TypedDateTimeNames {
/// use icu::locale::locale;
/// use writeable::assert_try_writeable_eq;
///
- /// let locale = &locale!("bn").into();
- ///
/// let mut names =
- /// TypedDateTimeNames::<(), TimeFieldSet>::try_new(&locale).unwrap();
+ /// TypedDateTimeNames::<(), TimeFieldSet>::try_new(locale!("bn").into()).unwrap();
/// names.include_fixed_decimal_formatter();
///
/// // Create a pattern for the time, which is all numbers
@@ -1132,7 +1133,7 @@ impl TypedDateTimeNames {
#[inline]
pub fn include_fixed_decimal_formatter(&mut self) -> Result<&mut Self, DataError> {
self.inner
- .load_fixed_decimal_formatter(&ExternalLoaderCompiledData, &self.locale)?;
+ .load_fixed_decimal_formatter(&ExternalLoaderCompiledData, self.prefs)?;
Ok(self)
}
@@ -1171,7 +1172,7 @@ impl TypedDateTimeNames {
+ DataProvider
+ ?Sized,
{
- let locale = &self.locale;
+ let locale = self.prefs;
self.inner.load_for_pattern(
&C::YearNamesV1Marker::bind(provider),
&C::MonthNamesV1Marker::bind(provider),
@@ -1211,7 +1212,7 @@ impl TypedDateTimeNames {
/// use writeable::assert_try_writeable_eq;
///
/// let mut names =
- /// TypedDateTimeNames::::try_new(&locale!("en").into())
+ /// TypedDateTimeNames::::try_new(locale!("en").into())
/// .unwrap();
///
/// // Create a pattern from a pattern string:
@@ -1242,7 +1243,7 @@ impl TypedDateTimeNames {
+ DataProvider
+ DataProvider,
{
- let locale = &self.locale;
+ let locale = self.prefs;
self.inner.load_for_pattern(
&C::YearNamesV1Marker::bind(&crate::provider::Baked),
&C::MonthNamesV1Marker::bind(&crate::provider::Baked),
@@ -1307,12 +1308,13 @@ impl RawDateTimeNames {
pub(crate) fn load_year_names(
&mut self,
provider: &P,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
field_length: FieldLength,
) -> Result<(), PatternLoadError>
where
P: BoundDataProvider + ?Sized,
{
+ let locale = provider.bound_marker().make_locale(prefs.locale_prefs);
let field = fields::Field {
symbol: FieldSymbol::Era,
length: field_length,
@@ -1331,7 +1333,7 @@ impl RawDateTimeNames {
_ => return Err(PatternLoadError::UnsupportedLength(field)),
},
),
- locale,
+ &locale,
),
..Default::default()
};
@@ -1345,13 +1347,14 @@ impl RawDateTimeNames {
pub(crate) fn load_month_names(
&mut self,
provider: &P,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
field_symbol: fields::Month,
field_length: FieldLength,
) -> Result<(), PatternLoadError>
where
P: BoundDataProvider + ?Sized,
{
+ let locale = provider.bound_marker().make_locale(prefs.locale_prefs);
let field = fields::Field {
symbol: FieldSymbol::Month(field_symbol),
length: field_length,
@@ -1371,7 +1374,7 @@ impl RawDateTimeNames {
_ => return Err(PatternLoadError::UnsupportedLength(field)),
},
),
- locale,
+ &locale,
),
..Default::default()
};
@@ -1385,12 +1388,13 @@ impl RawDateTimeNames {
pub(crate) fn load_day_period_names(
&mut self,
provider: &P,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
field_length: FieldLength,
) -> Result<(), PatternLoadError>
where
P: BoundDataProvider + ?Sized,
{
+ let locale = provider.bound_marker().make_locale(prefs.locale_prefs);
let field = fields::Field {
// Names for 'a' and 'b' are stored in the same data marker
symbol: FieldSymbol::DayPeriod(fields::DayPeriod::NoonMidnight),
@@ -1410,7 +1414,7 @@ impl RawDateTimeNames {
_ => return Err(PatternLoadError::UnsupportedLength(field)),
},
),
- locale,
+ &locale,
),
..Default::default()
};
@@ -1424,13 +1428,14 @@ impl RawDateTimeNames {
pub(crate) fn load_weekday_names(
&mut self,
provider: &P,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
field_symbol: fields::Weekday,
field_length: FieldLength,
) -> Result<(), PatternLoadError>
where
P: BoundDataProvider + ?Sized,
{
+ let locale = provider.bound_marker().make_locale(prefs.locale_prefs);
let field = fields::Field {
symbol: FieldSymbol::Weekday(field_symbol),
length: field_length,
@@ -1461,7 +1466,7 @@ impl RawDateTimeNames {
_ => return Err(PatternLoadError::UnsupportedLength(field)),
},
),
- locale,
+ &locale,
),
..Default::default()
};
@@ -1475,18 +1480,19 @@ impl RawDateTimeNames {
pub(crate) fn load_time_zone_essentials(
&mut self,
provider: &P,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
) -> Result<(), PatternLoadError>
where
P: BoundDataProvider + ?Sized,
{
+ let locale = provider.bound_marker().make_locale(prefs.locale_prefs);
let field = fields::Field {
symbol: FieldSymbol::TimeZone(fields::TimeZone::LocalizedOffset),
length: FieldLength::Four,
};
let variables = ();
let req = DataRequest {
- id: DataIdentifierBorrowed::for_locale(locale),
+ id: DataIdentifierBorrowed::for_locale(&locale),
..Default::default()
};
self.zone_essentials
@@ -1499,18 +1505,19 @@ impl RawDateTimeNames {
pub(crate) fn load_time_zone_location_names(
&mut self,
provider: &P,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
) -> Result<(), PatternLoadError>
where
P: BoundDataProvider + ?Sized,
{
+ let locale = provider.bound_marker().make_locale(prefs.locale_prefs);
let field = fields::Field {
symbol: FieldSymbol::TimeZone(fields::TimeZone::Location),
length: FieldLength::Four,
};
let variables = ();
let req = DataRequest {
- id: DataIdentifierBorrowed::for_locale(locale),
+ id: DataIdentifierBorrowed::for_locale(&locale),
..Default::default()
};
self.locations_root
@@ -1524,122 +1531,133 @@ impl RawDateTimeNames {
Ok(())
}
+ fn load_mz_periods(
+ &mut self,
+ provider: &P,
+ field: fields::Field,
+ ) -> Result<(), PatternLoadError>
+ where
+ P: BoundDataProvider + ?Sized,
+ {
+ let variables = ();
+ self.mz_periods
+ .load_put(provider, Default::default(), variables)
+ .map_err(|e| MaybePayloadError::into_load_error(e, field))?
+ .map_err(|e| PatternLoadError::Data(e, field))?;
+ Ok(())
+ }
+
pub(crate) fn load_time_zone_generic_long_names(
&mut self,
- mz_generic_long_provider: &(impl BoundDataProvider + ?Sized),
+ provider: &(impl BoundDataProvider + ?Sized),
mz_period_provider: &(impl BoundDataProvider + ?Sized),
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
) -> Result<(), PatternLoadError> {
+ let locale = provider.bound_marker().make_locale(prefs.locale_prefs);
let field = fields::Field {
symbol: FieldSymbol::TimeZone(fields::TimeZone::GenericNonLocation),
length: FieldLength::Four,
};
let variables = ();
let req = DataRequest {
- id: DataIdentifierBorrowed::for_locale(locale),
+ id: DataIdentifierBorrowed::for_locale(&locale),
..Default::default()
};
self.mz_generic_long
- .load_put(mz_generic_long_provider, req, variables)
- .map_err(|e| MaybePayloadError::into_load_error(e, field))?
- .map_err(|e| PatternLoadError::Data(e, field))?;
- self.mz_periods
- .load_put(mz_period_provider, Default::default(), variables)
+ .load_put(provider, req, variables)
.map_err(|e| MaybePayloadError::into_load_error(e, field))?
.map_err(|e| PatternLoadError::Data(e, field))?;
+ self.load_mz_periods(mz_period_provider, field)?;
Ok(())
}
pub(crate) fn load_time_zone_generic_short_names(
&mut self,
- mz_generic_short_provider: &(impl BoundDataProvider + ?Sized),
+ provider: &(impl BoundDataProvider + ?Sized),
mz_period_provider: &(impl BoundDataProvider + ?Sized),
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
) -> Result<(), PatternLoadError> {
+ let locale = provider.bound_marker().make_locale(prefs.locale_prefs);
let field = fields::Field {
symbol: FieldSymbol::TimeZone(fields::TimeZone::GenericNonLocation),
length: FieldLength::One,
};
let variables = ();
let req = DataRequest {
- id: DataIdentifierBorrowed::for_locale(locale),
+ id: DataIdentifierBorrowed::for_locale(&locale),
..Default::default()
};
self.mz_generic_short
- .load_put(mz_generic_short_provider, req, variables)
- .map_err(|e| MaybePayloadError::into_load_error(e, field))?
- .map_err(|e| PatternLoadError::Data(e, field))?;
- self.mz_periods
- .load_put(mz_period_provider, Default::default(), variables)
+ .load_put(provider, req, variables)
.map_err(|e| MaybePayloadError::into_load_error(e, field))?
.map_err(|e| PatternLoadError::Data(e, field))?;
+ self.load_mz_periods(mz_period_provider, field)?;
Ok(())
}
pub(crate) fn load_time_zone_specific_long_names(
&mut self,
- mz_specific_long_provider: &(impl BoundDataProvider + ?Sized),
+ provider: &(impl BoundDataProvider + ?Sized),
mz_period_provider: &(impl BoundDataProvider + ?Sized),
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
) -> Result<(), PatternLoadError> {
+ let locale = provider.bound_marker().make_locale(prefs.locale_prefs);
let field = fields::Field {
symbol: FieldSymbol::TimeZone(fields::TimeZone::SpecificNonLocation),
length: FieldLength::Four,
};
let variables = ();
let req = DataRequest {
- id: DataIdentifierBorrowed::for_locale(locale),
+ id: DataIdentifierBorrowed::for_locale(&locale),
..Default::default()
};
self.mz_specific_long
- .load_put(mz_specific_long_provider, req, variables)
- .map_err(|e| MaybePayloadError::into_load_error(e, field))?
- .map_err(|e| PatternLoadError::Data(e, field))?;
- self.mz_periods
- .load_put(mz_period_provider, Default::default(), variables)
+ .load_put(provider, req, variables)
.map_err(|e| MaybePayloadError::into_load_error(e, field))?
.map_err(|e| PatternLoadError::Data(e, field))?;
+ self.load_mz_periods(mz_period_provider, field)?;
Ok(())
}
pub(crate) fn load_time_zone_specific_short_names(
&mut self,
- mz_specific_short_provider: &(impl BoundDataProvider + ?Sized),
+ provider: &(impl BoundDataProvider + ?Sized),
mz_period_provider: &(impl BoundDataProvider + ?Sized),
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
) -> Result<(), PatternLoadError> {
+ let locale = provider.bound_marker().make_locale(prefs.locale_prefs);
let field = fields::Field {
symbol: FieldSymbol::TimeZone(fields::TimeZone::SpecificNonLocation),
length: FieldLength::One,
};
let variables = ();
let req = DataRequest {
- id: DataIdentifierBorrowed::for_locale(locale),
+ id: DataIdentifierBorrowed::for_locale(&locale),
..Default::default()
};
self.mz_specific_short
- .load_put(mz_specific_short_provider, req, variables)
- .map_err(|e| MaybePayloadError::into_load_error(e, field))?
- .map_err(|e| PatternLoadError::Data(e, field))?;
- self.mz_periods
- .load_put(mz_period_provider, Default::default(), variables)
+ .load_put(provider, req, variables)
.map_err(|e| MaybePayloadError::into_load_error(e, field))?
.map_err(|e| PatternLoadError::Data(e, field))?;
+ self.load_mz_periods(mz_period_provider, field)?;
Ok(())
}
pub(crate) fn load_fixed_decimal_formatter(
&mut self,
loader: &impl FixedDecimalFormatterLoader,
- locale: &DataLocale,
+ prefs: DateTimeFormatterPreferences,
) -> Result<(), DataError> {
if self.fixed_decimal_formatter.is_some() {
return Ok(());
}
let mut options = FixedDecimalFormatterOptions::default();
options.grouping_strategy = GroupingStrategy::Never;
- self.fixed_decimal_formatter =
- Some(FixedDecimalFormatterLoader::load(loader, locale, options)?);
+ self.fixed_decimal_formatter = Some(FixedDecimalFormatterLoader::load(
+ loader,
+ (&prefs).into(),
+ options,
+ )?);
Ok(())
}
@@ -1662,7 +1680,7 @@ impl