@@ -10,7 +10,7 @@ use super::{
1010use crate :: error:: ErrorField ;
1111use crate :: fieldsets:: enums:: { CompositeDateTimeFieldSet , CompositeFieldSet } ;
1212use crate :: provider:: fields:: { self , FieldLength , FieldSymbol } ;
13- use crate :: provider:: neo:: { marker_attrs, * } ;
13+ use crate :: provider:: neo:: { get_year_name_from_map , marker_attrs, MonthNames , YearNames , * } ;
1414use crate :: provider:: pattern:: PatternItem ;
1515use crate :: provider:: time_zones:: tz;
1616use crate :: size_test_macro:: size_test;
@@ -19,7 +19,7 @@ use crate::{external_loaders::*, DateTimeFormatterPreferences};
1919use crate :: { scaffold:: * , DateTimeFormatter , DateTimeFormatterLoadError } ;
2020use core:: fmt;
2121use core:: marker:: PhantomData ;
22- use icu_calendar:: types:: { EraYear , MonthCode } ;
22+ use icu_calendar:: types:: { EraYear , MonthCode , Weekday } ;
2323use icu_calendar:: AnyCalendar ;
2424use icu_decimal:: options:: DecimalFormatterOptions ;
2525use icu_decimal:: options:: GroupingStrategy ;
@@ -2826,6 +2826,200 @@ where
28262826 }
28272827}
28282828
2829+ impl < C , FSet : DateTimeNamesMarker > FixedCalendarDateTimeNames < C , FSet >
2830+ where
2831+ FSet :: WeekdayNames : NamesContainer <
2832+ WeekdayNamesV1 ,
2833+ WeekdayNameLength ,
2834+ Container = DataPayloadWithVariables < WeekdayNamesV1 , WeekdayNameLength > ,
2835+ > ,
2836+ {
2837+ /// Gets the weekday name for the specified length and weekday if the data is loaded.
2838+ ///
2839+ /// Returns `Some` if the data for the specified length is loaded, or `None` if not loaded.
2840+ ///
2841+ /// # Examples
2842+ ///
2843+ /// ```
2844+ /// use icu::calendar::types::Weekday;
2845+ /// use icu::calendar::Gregorian;
2846+ /// use icu::datetime::pattern::{FixedCalendarDateTimeNames, WeekdayNameLength};
2847+ /// use icu::locale::locale;
2848+ ///
2849+ /// let mut names =
2850+ /// FixedCalendarDateTimeNames::<Gregorian>::try_new(locale!("en").into())
2851+ /// .unwrap();
2852+ ///
2853+ /// // Before loading data, the getter returns None:
2854+ /// assert_eq!(names.get_weekday(Weekday::Monday, WeekdayNameLength::Wide), None);
2855+ ///
2856+ /// // Load the weekday names:
2857+ /// names
2858+ /// .include_weekday_names(WeekdayNameLength::Wide)
2859+ /// .unwrap();
2860+ ///
2861+ /// // Now we can get the weekday name for the loaded length:
2862+ /// assert_eq!(
2863+ /// names.get_weekday(Weekday::Monday, WeekdayNameLength::Wide),
2864+ /// Some("Monday")
2865+ /// );
2866+ ///
2867+ /// // But other lengths are not loaded:
2868+ /// assert_eq!(
2869+ /// names.get_weekday(Weekday::Monday, WeekdayNameLength::Abbreviated),
2870+ /// None
2871+ /// );
2872+ /// ```
2873+ pub fn get_weekday ( & self , weekday : Weekday , length : WeekdayNameLength ) -> Option < & str > {
2874+ let borrowed = self . inner . as_borrowed ( ) ;
2875+ borrowed
2876+ . weekday_names
2877+ . get_with_variables ( length)
2878+ . and_then ( |names| names. names . get ( ( weekday as usize ) % 7 ) )
2879+ }
2880+ }
2881+
2882+ impl < C : CldrCalendar , FSet : DateTimeNamesMarker > FixedCalendarDateTimeNames < C , FSet >
2883+ where
2884+ FSet :: MonthNames : NamesContainer <
2885+ MonthNamesV1 ,
2886+ MonthNameLength ,
2887+ Container = DataPayloadWithVariables < MonthNamesV1 , MonthNameLength > ,
2888+ > ,
2889+ {
2890+ /// Gets the month name for the specified length and month code if the data is loaded.
2891+ ///
2892+ /// Returns `Some` if the data for the specified length is loaded and the month code is valid,
2893+ /// or `None` if not loaded or the month code is invalid.
2894+ ///
2895+ /// # Examples
2896+ ///
2897+ /// ```
2898+ /// use icu::calendar::types::MonthCode;
2899+ /// use icu::calendar::Gregorian;
2900+ /// use icu::datetime::pattern::{FixedCalendarDateTimeNames, MonthNameLength};
2901+ /// use icu::locale::locale;
2902+ ///
2903+ /// let mut names =
2904+ /// FixedCalendarDateTimeNames::<Gregorian>::try_new(locale!("en").into())
2905+ /// .unwrap();
2906+ ///
2907+ /// // Before loading data, the getter returns None:
2908+ /// assert_eq!(
2909+ /// names.get_month(MonthCode(tinystr::tinystr!(4, "M01")), MonthNameLength::Wide),
2910+ /// None
2911+ /// );
2912+ ///
2913+ /// // Load the month names:
2914+ /// names
2915+ /// .include_month_names(MonthNameLength::Wide)
2916+ /// .unwrap();
2917+ ///
2918+ /// // Now we can get the month name for the loaded length:
2919+ /// assert_eq!(
2920+ /// names.get_month(MonthCode(tinystr::tinystr!(4, "M01")), MonthNameLength::Wide),
2921+ /// Some("January")
2922+ /// );
2923+ ///
2924+ /// // But other lengths are not loaded:
2925+ /// assert_eq!(
2926+ /// names.get_month(
2927+ /// MonthCode(tinystr::tinystr!(4, "M01")),
2928+ /// MonthNameLength::Abbreviated
2929+ /// ),
2930+ /// None
2931+ /// );
2932+ /// ```
2933+ pub fn get_month ( & self , month_code : MonthCode , length : MonthNameLength ) -> Option < & str > {
2934+ let borrowed = self . inner . as_borrowed ( ) ;
2935+ let month_names = borrowed. month_names . get_with_variables ( length) ?;
2936+
2937+ let ( month_number, is_leap) = month_code. parsed ( ) ?;
2938+ let month_index = usize:: from ( month_number. checked_sub ( 1 ) ?) ;
2939+
2940+ match month_names {
2941+ MonthNames :: Linear ( linear) => {
2942+ if is_leap {
2943+ None
2944+ } else {
2945+ linear. get ( month_index)
2946+ }
2947+ }
2948+ MonthNames :: LeapLinear ( leap_linear) => {
2949+ let num_months = leap_linear. len ( ) / 2 ;
2950+ if is_leap {
2951+ leap_linear. get ( month_index + num_months)
2952+ } else if month_index < num_months {
2953+ leap_linear. get ( month_index)
2954+ } else {
2955+ None
2956+ }
2957+ }
2958+ MonthNames :: LeapNumeric ( _) => None ,
2959+ }
2960+ }
2961+ }
2962+
2963+ impl < C : CldrCalendar , FSet : DateTimeNamesMarker > FixedCalendarDateTimeNames < C , FSet >
2964+ where
2965+ FSet :: YearNames : NamesContainer <
2966+ YearNamesV1 ,
2967+ YearNameLength ,
2968+ Container = DataPayloadWithVariables < YearNamesV1 , YearNameLength > ,
2969+ > ,
2970+ {
2971+ /// Gets the era name for the specified length and era if the data is loaded.
2972+ ///
2973+ /// Returns `Some` if the data for the specified length is loaded and the era is valid,
2974+ /// or `None` if not loaded or the era is invalid.
2975+ ///
2976+ /// Note: This is a low-level API. The `era_year` parameter is typically obtained from
2977+ /// calendar date operations. Most users should use the formatting APIs instead.
2978+ ///
2979+ /// # Examples
2980+ ///
2981+ /// ```
2982+ /// use icu::calendar::{Date, Gregorian};
2983+ /// use icu::datetime::pattern::{FixedCalendarDateTimeNames, YearNameLength};
2984+ /// use icu::locale::locale;
2985+ ///
2986+ /// let mut names =
2987+ /// FixedCalendarDateTimeNames::<Gregorian>::try_new(locale!("en").into())
2988+ /// .unwrap();
2989+ ///
2990+ /// // Get era from a date
2991+ /// let date = Date::try_new_gregorian(2024, 1, 1).unwrap();
2992+ /// let era_year = date.era_year();
2993+ ///
2994+ /// // Before loading data, the getter returns None:
2995+ /// assert_eq!(names.get_era(&era_year, YearNameLength::Wide), None);
2996+ ///
2997+ /// // Load the year names:
2998+ /// names.include_year_names(YearNameLength::Wide).unwrap();
2999+ ///
3000+ /// // Now we can get the era name for the loaded length:
3001+ /// assert_eq!(names.get_era(&era_year, YearNameLength::Wide), Some("Anno Domini"));
3002+ ///
3003+ /// // But other lengths are not loaded:
3004+ /// assert_eq!(
3005+ /// names.get_era(&era_year, YearNameLength::Abbreviated),
3006+ /// None
3007+ /// );
3008+ /// ```
3009+ pub fn get_era ( & self , era_year : & EraYear , length : YearNameLength ) -> Option < & str > {
3010+ let borrowed = self . inner . as_borrowed ( ) ;
3011+ let year_names = borrowed. year_names . get_with_variables ( length) ?;
3012+
3013+ match ( year_names, era_year. era_index ) {
3014+ ( YearNames :: VariableEras ( era_names) , None ) => {
3015+ get_year_name_from_map ( era_names, era_year. era . as_str ( ) . into ( ) )
3016+ }
3017+ ( YearNames :: FixedEras ( era_names) , Some ( index) ) => era_names. get ( index as usize ) ,
3018+ _ => None ,
3019+ }
3020+ }
3021+ }
3022+
28293023impl < FSet : DateTimeNamesMarker > DateTimeNames < FSet > {
28303024 /// Maps a [`FixedCalendarDateTimeNames`] of a specific `FSet` to a more general `FSet`.
28313025 ///
0 commit comments