From d3cbc2855e2623056e72cb209b3dc39e04e47afc Mon Sep 17 00:00:00 2001 From: mildgravitas <10595307+mildgravitas@users.noreply.github.com> Date: Mon, 21 Mar 2022 14:24:03 +0100 Subject: [PATCH] Add support for week-of-month. (#1468) Contrary to UTS 35 this always uses min_days = 1 as there's no month of week-of-month field so there would be inconsistencies otherwise (e.g. in the ISO calendar 2021-01-01 is the last week of December but 'MMMMW' would have it formatted as 'week 5 of January'). --- components/calendar/src/arithmetic.rs | 50 ++++++++++++++++++ components/datetime/src/date.rs | 50 +++++++++++++++--- components/datetime/src/fields/symbols.rs | 9 +--- components/datetime/src/format/datetime.rs | 12 +++-- components/datetime/src/options/components.rs | 20 ++++--- .../datetime/src/pattern/runtime/plural.rs | 2 +- components/datetime/src/skeleton/error.rs | 2 - components/datetime/src/skeleton/mod.rs | 5 +- .../tests/components-exact-matches.json | 20 ++++++- .../tests/components-partial-matches.json | 18 +++++++ .../datetime/skeletons@1/gregory/ar-EG.json | 1 + .../json/datetime/skeletons@1/gregory/ar.json | 1 + .../json/datetime/skeletons@1/gregory/bn.json | 1 + .../datetime/skeletons@1/gregory/ccp.json | 1 + .../datetime/skeletons@1/gregory/en-001.json | 1 + .../datetime/skeletons@1/gregory/en-ZA.json | 1 + .../json/datetime/skeletons@1/gregory/en.json | 1 + .../datetime/skeletons@1/gregory/es-AR.json | 1 + .../json/datetime/skeletons@1/gregory/es.json | 1 + .../datetime/skeletons@1/gregory/fil.json | 9 ++++ .../json/datetime/skeletons@1/gregory/fr.json | 1 + .../json/datetime/skeletons@1/gregory/ja.json | 1 + .../json/datetime/skeletons@1/gregory/ru.json | 1 + .../datetime/skeletons@1/gregory/sr-Cyrl.json | 1 + .../datetime/skeletons@1/gregory/sr-Latn.json | 1 + .../json/datetime/skeletons@1/gregory/sr.json | 1 + .../json/datetime/skeletons@1/gregory/th.json | 1 + .../json/datetime/skeletons@1/gregory/tr.json | 1 + .../datetime/skeletons@1/gregory/und.json | 1 + provider/testdata/data/testdata.postcard | Bin 4504771 -> 4505794 bytes 30 files changed, 179 insertions(+), 36 deletions(-) diff --git a/components/calendar/src/arithmetic.rs b/components/calendar/src/arithmetic.rs index 7b9f97a97a8..5b91d962301 100644 --- a/components/calendar/src/arithmetic.rs +++ b/components/calendar/src/arithmetic.rs @@ -181,6 +181,31 @@ pub mod week_of { } } + /// Computes & returns the week of given month or year accoding to a calendar with min_week_days = 1. + /// + /// # Arguments + /// - first_weekday: The first day of a week. + /// - day: 1-based day of the month or year. + /// - week_day: The weekday of `day`. + pub fn simple_week_of(first_weekday: IsoWeekday, day: u16, week_day: IsoWeekday) -> u16 { + let calendar = CalendarInfo { + first_weekday, + min_week_days: 1, + }; + + week_of( + &calendar, + // The duration of the current and previous unit does not influence the result if min_week_days = 1 + // so we only need to use a valid value. + MIN_UNIT_DAYS, + MIN_UNIT_DAYS, + day, + week_day, + ) + .expect("week_of should can't fail with MIN_UNIT_DAYS") + .week + } + #[cfg(test)] mod tests { use super::{week_of, CalendarInfo, RelativeUnit, RelativeWeek, UnitInfo, WeekOf}; @@ -422,4 +447,29 @@ pub mod week_of { Ok(()) } } + + #[test] + fn test_simple_week_of() { + // The 1st is a Monday and the week starts on Mondays. + assert_eq!( + simple_week_of(IsoWeekday::Monday, 2, IsoWeekday::Tuesday), + 1 + ); + assert_eq!(simple_week_of(IsoWeekday::Monday, 7, IsoWeekday::Sunday), 1); + assert_eq!(simple_week_of(IsoWeekday::Monday, 8, IsoWeekday::Monday), 2); + + // The 1st is a Wednesday and the week starts on Tuesdays. + assert_eq!( + simple_week_of(IsoWeekday::Tuesday, 1, IsoWeekday::Wednesday), + 1 + ); + assert_eq!( + simple_week_of(IsoWeekday::Tuesday, 6, IsoWeekday::Monday), + 1 + ); + assert_eq!( + simple_week_of(IsoWeekday::Tuesday, 7, IsoWeekday::Tuesday), + 2 + ); + } } diff --git a/components/datetime/src/date.rs b/components/datetime/src/date.rs index 28e09ae31e8..b8fc6e2e7b1 100644 --- a/components/datetime/src/date.rs +++ b/components/datetime/src/date.rs @@ -103,8 +103,10 @@ pub trait LocalizedDateTimeInput { /// For example, December 31, 2020 is part of the first week of 2021. fn year_week(&self) -> Result; - /// The week of the month according to UTS 35. - fn week_of_month(&self) -> WeekOfMonth; + /// The week of the month. + /// + /// For example, January 1, 2021 is part of the first week of January. + fn week_of_month(&self) -> Result; /// The week number of the year. /// @@ -163,6 +165,32 @@ fn week_of_year( Ok(WeekOfYear(u32::from(week.week))) } +/// Returns the week of month according to a calendar with min_week_days = 1. +/// +/// This is different from what the UTS35 spec describes [1] but the latter is +/// missing a month of week-of-month field so following the spec would result +/// in inconsistencies (e.g. in the ISO calendar 2021-01-01 is the last week +/// of December but 'MMMMW' would have it formatted as 'week 5 of January'). +/// +/// 1: https://www.unicode.org/reports/tr35/tr35-55/tr35-dates.html#Date_Patterns_Week_Of_Year +fn week_of_month( + datetime: &T, + first_weekday: IsoWeekday, +) -> Result { + let day_of_month = datetime + .day_of_month() + .ok_or(DateTimeError::MissingInput("DateTimeInput::day_of_month"))?; + + let week = week_of::simple_week_of( + first_weekday, + day_of_month.0 as u16, + datetime + .iso_weekday() + .ok_or(DateTimeError::MissingInput("DateTimeInput::iso_weekday"))?, + ); + Ok(WeekOfMonth(u32::from(week))) +} + impl<'data, T: DateTimeInput> DateTimeInputWithLocale<'data, T> { pub fn new( data: &'data T, @@ -201,8 +229,13 @@ impl<'data, T: DateTimeInput> LocalizedDateTimeInput for DateTimeInputWithLoc ) } - fn week_of_month(&self) -> WeekOfMonth { - todo!("#488") + fn week_of_month(&self) -> Result { + week_of_month( + self.data, + self.calendar + .expect("calendar must be provided when using week of methods") + .first_weekday, + ) } fn week_of_year(&self) -> Result { @@ -233,8 +266,13 @@ impl<'data, T: ZonedDateTimeInput> LocalizedDateTimeInput ) } - fn week_of_month(&self) -> WeekOfMonth { - todo!("#488") + fn week_of_month(&self) -> Result { + week_of_month( + self.data, + self.calendar + .expect("calendar must be provided when using week of methods") + .first_weekday, + ) } fn week_of_year(&self) -> Result { diff --git a/components/datetime/src/fields/symbols.rs b/components/datetime/src/fields/symbols.rs index c1e39230267..96ea9a7028c 100644 --- a/components/datetime/src/fields/symbols.rs +++ b/components/datetime/src/fields/symbols.rs @@ -231,14 +231,7 @@ impl TryFrom for FieldSymbol { }) .or_else(|_| Year::try_from(ch).map(Self::Year)) .or_else(|_| Month::try_from(ch).map(Self::Month)) - .or_else(|_| { - if ch == 'w' { - Week::try_from(ch).map(Self::Week) - } else { - // TODO(#488): Add support for 'W'. - Err(SymbolError::Unknown(ch)) - } - }) + .or_else(|_| Week::try_from(ch).map(Self::Week)) .or_else(|_| Day::try_from(ch).map(Self::Day)) .or_else(|_| Weekday::try_from(ch).map(Self::Weekday)) .or_else(|_| DayPeriod::try_from(ch).map(Self::DayPeriod)) diff --git a/components/datetime/src/format/datetime.rs b/components/datetime/src/format/datetime.rs index 251a4024ef2..2a38a82d547 100644 --- a/components/datetime/src/format/datetime.rs +++ b/components/datetime/src/format/datetime.rs @@ -215,10 +215,14 @@ where w.write_str(symbol)? } }, - FieldSymbol::Week(Week::WeekOfYear) => { - format_number(w, datetime.week_of_year()?.0 as isize, field.length)? - } - field @ FieldSymbol::Week(_) => return Err(Error::UnsupportedField(field)), + FieldSymbol::Week(week) => match week { + Week::WeekOfYear => { + format_number(w, datetime.week_of_year()?.0 as isize, field.length)? + } + Week::WeekOfMonth => { + format_number(w, datetime.week_of_month()?.0 as isize, field.length)? + } + }, FieldSymbol::Weekday(weekday) => { let dow = datetime .datetime() diff --git a/components/datetime/src/options/components.rs b/components/datetime/src/options/components.rs index 86b709f2ee7..a0effe27d85 100644 --- a/components/datetime/src/options/components.rs +++ b/components/datetime/src/options/components.rs @@ -93,9 +93,7 @@ pub struct Bag { pub year: Option, /// Include the month, such as "April" or "Apr". pub month: Option, - /// Include the week, such as "1st" or "1". - #[doc(hidden)] - // TODO(#488): make visible once fully supported. + /// Include the week number, such as "51st" or "51" for week 51. pub week: Option, /// Include the day, such as "07" or "7". pub day: Option, @@ -390,7 +388,7 @@ pub enum Month { Numeric, /// The two-digit value of the month, such as "04". TwoDigit, - /// The two-digit value of the month, such as "April". + /// The long value of the month, such as "April". Long, /// The short value of the month, such as "Apr". Short, @@ -400,10 +398,10 @@ pub enum Month { // Each enum variant is documented with the UTS 35 field information from: // https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table -// -/// Options for displaying the current week for the `components::`[`Bag`]. -#[doc(hidden)] -// TODO(#488): make visible once fully supported. + +/// Options for displaying the current week number for the `components::`[`Bag`]. +/// +/// Week numbers are relative to either a month or year, e.g. 'week 3 of January' or 'week 40 of 2000'. #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr( feature = "serialize", @@ -411,11 +409,11 @@ pub enum Month { serde(rename_all = "kebab-case") )] pub enum Week { - /// The week of the month, such as "3". + /// The week of the month, such as the "3" in "week 3 of January". WeekOfMonth, - /// The numeric value of the week of the year, such as "8". + /// The numeric value of the week of the year, such as the "8" in "week 8 of 2000". NumericWeekOfYear, - /// The two-digit value of the week of the year, such as "08". + /// The two-digit value of the week of the year, such as the "08" in "2000-W08". TwoDigitWeekOfYear, } diff --git a/components/datetime/src/pattern/runtime/plural.rs b/components/datetime/src/pattern/runtime/plural.rs index 1ec8c9d80f9..418e4103db8 100644 --- a/components/datetime/src/pattern/runtime/plural.rs +++ b/components/datetime/src/pattern/runtime/plural.rs @@ -150,7 +150,7 @@ impl<'data> PatternPlurals<'data> { Self::SinglePattern(pattern) => Ok(pattern), Self::MultipleVariants(plural_pattern) => { let week_number = match plural_pattern.pivot_field() { - Week::WeekOfMonth => loc_datetime.week_of_month().0, + Week::WeekOfMonth => loc_datetime.week_of_month()?.0, Week::WeekOfYear => loc_datetime.week_of_year()?.0, }; let category = ordinal_rules diff --git a/components/datetime/src/skeleton/error.rs b/components/datetime/src/skeleton/error.rs index c444c9f25ee..167955d440d 100644 --- a/components/datetime/src/skeleton/error.rs +++ b/components/datetime/src/skeleton/error.rs @@ -60,8 +60,6 @@ impl From for SkeletonError { match ch { // TODO(#487) - Flexible day periods 'B' - // TODO(#502) - Week of month - | 'W' // TODO(#501) - Quarters | 'Q' => Self::SymbolUnimplemented(ch), diff --git a/components/datetime/src/skeleton/mod.rs b/components/datetime/src/skeleton/mod.rs index eb4cd56c4ba..101627baa83 100644 --- a/components/datetime/src/skeleton/mod.rs +++ b/components/datetime/src/skeleton/mod.rs @@ -204,7 +204,8 @@ mod test { #[rustfmt::skip] const SUPPORTED_STRING_SKELETONS: &[&str] = &[ "E", "dEEEE", "EHm", "EHms", "dE", "Ehm", "Ehms", "H", "HHmm", "HHmmss", "Hm", "Hms", "M", - "MdEEEE", "MdE", "MMM", "MMMdEEEE", "MMMdE", "MMMM", "MMMMdEEEE", "MMMMdE", "MMMMd", + "MdEEEE", "MdE", "MMM", "MMMdEEEE", "MMMdE", "MMMM", "MMMMW", + "MMMMdEEEE", "MMMMdE", "MMMMd", "MMMMdd", "MMMd", "MMMdd", "MMd", "MMdd", "Md", "Mdd", "d", "h", "hm", "hms", "mmss", "ms", "y", "yM", "yMdEEEE", "yMdE", "yMM", "yMMM", "yMMMdEEEE", "yMMMdE", "yMMMM", "yMMMMdEEEE", "yMMMMdE", "yMMMMdcccc", "yMMMMd", "yMMMd", "yMMdd", "yMd", "yw", @@ -221,8 +222,6 @@ mod test { const UNSUPPORTED_STRING_SKELETONS: &[&str] = &[ // TODO(#487) - Flexible day periods "Bh", "Bhm", "Bhms", "EBhm", "EBhms", - // TODO(#502) - Week of month - "MMMMW", // TODO(#501) - Quarters "yQ", "yQQQ", "yQQQQ", ]; diff --git a/components/datetime/tests/fixtures/tests/components-exact-matches.json b/components/datetime/tests/fixtures/tests/components-exact-matches.json index d43d69d0f02..6a833a4d6c1 100644 --- a/components/datetime/tests/fixtures/tests/components-exact-matches.json +++ b/components/datetime/tests/fixtures/tests/components-exact-matches.json @@ -512,7 +512,7 @@ } }, { - "description": "Exact match for: yw => week' w 'of' Y", + "description": "Exact match for: yw => 'week' w 'of' Y", "input": { "locale": "en", "value": "2016-04-17T08:25:07.000", @@ -530,5 +530,23 @@ "en-ZA": "week 17 of 2016" } } + }, + { + "description": "Exact match for: MMMMW -> 'week' W 'of' MMMM", + "input": { + "locale": "en", + "value": "2022-01-01T08:25:07.000", + "options": { + "components": { + "month": "long", + "week": "week-of-month" + } + } + }, + "output": { + "values": { + "en": "week 1 of January" + } + } } ] diff --git a/components/datetime/tests/fixtures/tests/components-partial-matches.json b/components/datetime/tests/fixtures/tests/components-partial-matches.json index baa1db04bb2..006a5b1642c 100644 --- a/components/datetime/tests/fixtures/tests/components-partial-matches.json +++ b/components/datetime/tests/fixtures/tests/components-partial-matches.json @@ -69,5 +69,23 @@ "en": "week 53 of 2002" } } + }, + { + "description": "Partial match for: MMMMWEEEE -> MMMMW -> 'week' W 'of' MMMM", + "input": { + "value": "2002-12-31T08:25:07.000", + "options": { + "components": { + "month": "long", + "week": "week-of-month", + "weekday": "long" + } + } + }, + "output": { + "values": { + "en": "week 1 of December" + } + } } ] diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/ar-EG.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/ar-EG.json index 74c2442ea7e..5c0ded3eb0d 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/ar-EG.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/ar-EG.json @@ -21,6 +21,7 @@ "MMM": "LLL", "MMMd": "d MMM", "MMMdE": "E، d MMM", + "MMMMW": "الأسبوع W من MMMM", "MMMMd": "d MMMM", "MMMMdE": "E، d MMMM", "d": "d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/ar.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/ar.json index 74c2442ea7e..5c0ded3eb0d 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/ar.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/ar.json @@ -21,6 +21,7 @@ "MMM": "LLL", "MMMd": "d MMM", "MMMdE": "E، d MMM", + "MMMMW": "الأسبوع W من MMMM", "MMMMd": "d MMMM", "MMMMdE": "E، d MMMM", "d": "d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/bn.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/bn.json index 52d29260320..50df406d0fa 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/bn.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/bn.json @@ -21,6 +21,7 @@ "MMM": "LLL", "MMMd": "d MMM", "MMMdE": "E d MMM", + "MMMMW": "MMMM এর Wয় সপ্তাহ", "MMMMd": "d MMMM", "MMMMdE": "E d MMMM", "d": "d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/ccp.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/ccp.json index 9af9cb5118b..ef4919cd7f7 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/ccp.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/ccp.json @@ -21,6 +21,7 @@ "MMM": "LLL", "MMMd": "d MMM", "MMMdE": "E d MMM", + "MMMMW": "MMMM 𑄃𑄬𑄢𑄴 𑄠𑄴 𑄥𑄛𑄴𑄖 W", "MMMMd": "d MMMM", "MMMMdE": "E d MMMM", "d": "d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/en-001.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/en-001.json index dac6859da01..f233688eea3 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/en-001.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/en-001.json @@ -20,6 +20,7 @@ "MMM": "LLL", "MMMd": "d MMM", "MMMdE": "E, d MMM", + "MMMMW": "'week' W 'of' MMMM", "MMMMd": "d MMMM", "d": "d", "dE": "E d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/en-ZA.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/en-ZA.json index 420ab53fb73..31c446a2068 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/en-ZA.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/en-ZA.json @@ -20,6 +20,7 @@ "MMM": "LLL", "MMMd": "dd MMM", "MMMdE": "E, dd MMM", + "MMMMW": "'week' W 'of' MMMM", "MMMMd": "d MMMM", "d": "d", "dE": "E d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/en.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/en.json index c52a21bc7f0..910033e018c 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/en.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/en.json @@ -19,6 +19,7 @@ "MMM": "LLL", "MMMd": "MMM d", "MMMdE": "E, MMM d", + "MMMMW": "'week' W 'of' MMMM", "MMMMd": "MMMM d", "d": "d", "dE": "d E", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/es-AR.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/es-AR.json index d3504d9fd92..4da1cb4b484 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/es-AR.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/es-AR.json @@ -28,6 +28,7 @@ "MMMd": "d MMM", "MMMdE": "E, d MMM", "MMMdd": "dd-MMM", + "MMMMW": "'semana' W 'de' MMMM", "MMMMd": "d 'de' MMMM", "MMMMdE": "E, d 'de' MMMM", "d": "d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/es.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/es.json index 56b4555b0cf..57dc745be5b 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/es.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/es.json @@ -27,6 +27,7 @@ "MMM": "LLL", "MMMd": "d MMM", "MMMdE": "E, d MMM", + "MMMMW": "'semana' W 'de' MMMM", "MMMMd": "d 'de' MMMM", "MMMMdE": "E, d 'de' MMMM", "d": "d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/fil.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/fil.json index 5bd010626b0..0e76f474170 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/fil.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/fil.json @@ -28,6 +28,15 @@ "MMM": "LLL", "MMMd": "MMM d", "MMMdE": "E, MMM d", + "MMMMW": { + "pivot_field": "WeekOfMonth", + "zero": null, + "one": "'ika-'W 'linggo ng' MMMM", + "two": null, + "few": null, + "many": null, + "other": "'linggo' W 'ng' MMMM" + }, "MMMMd": "MMMM d", "MMMMdE": "E, MMMM d", "d": "d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/fr.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/fr.json index 6c4498deda2..872771b818c 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/fr.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/fr.json @@ -19,6 +19,7 @@ "MMM": "LLL", "MMMd": "d MMM", "MMMdE": "E d MMM", + "MMMMW": "'semaine' W (MMMM)", "MMMMd": "d MMMM", "d": "d", "dE": "E d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/ja.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/ja.json index 531aa4883ea..68a4ec4198a 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/ja.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/ja.json @@ -25,6 +25,7 @@ "MMMd": "M月d日", "MMMdE": "M月d日(E)", "MMMdEEEE": "M月d日EEEE", + "MMMMW": "M月第W週", "MMMMd": "M月d日", "d": "d日", "dE": "d日(E)", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/ru.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/ru.json index bbc23007ea3..9afc896f473 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/ru.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/ru.json @@ -21,6 +21,7 @@ "MMM": "LLL", "MMMd": "d MMM", "MMMdE": "ccc, d MMM", + "MMMMW": "W-я неделя MMMM", "MMMMd": "d MMMM", "d": "d", "dE": "ccc, d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/sr-Cyrl.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/sr-Cyrl.json index 7d432fc3ec9..c28078894d3 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/sr-Cyrl.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/sr-Cyrl.json @@ -23,6 +23,7 @@ "MMMd": "d. MMM", "MMMdE": "E d. MMM", "MMMdd": "dd.MMM", + "MMMMW": "W. седмица у MMMM.", "MMMMd": "d. MMMM", "MMMMdE": "E, d. MMMM", "d": "d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/sr-Latn.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/sr-Latn.json index 571b46ac73f..f277d84ff19 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/sr-Latn.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/sr-Latn.json @@ -23,6 +23,7 @@ "MMMd": "d. MMM", "MMMdE": "E d. MMM", "MMMdd": "dd.MMM", + "MMMMW": "W'. sedmica u' MMMM.", "MMMMd": "d. MMMM", "MMMMdE": "E, d. MMMM", "d": "d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/sr.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/sr.json index 7d432fc3ec9..c28078894d3 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/sr.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/sr.json @@ -23,6 +23,7 @@ "MMMd": "d. MMM", "MMMdE": "E d. MMM", "MMMdd": "dd.MMM", + "MMMMW": "W. седмица у MMMM.", "MMMMd": "d. MMMM", "MMMMdE": "E, d. MMMM", "d": "d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/th.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/th.json index 79603155f3a..5c38152df34 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/th.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/th.json @@ -25,6 +25,7 @@ "MMMd": "d MMM", "MMMdE": "E d MMM", "MMMdEEEE": "EEEEที่ d MMM", + "MMMMW": "สัปดาห์ที่ W ของเดือนMMMM", "MMMMd": "d MMMM", "MMMMdE": "E d MMMM", "MMMMdEEEE": "EEEEที่ d MMMM", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/tr.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/tr.json index d0d72b1eabb..6c91c60da93 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/tr.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/tr.json @@ -20,6 +20,7 @@ "MMM": "LLL", "MMMd": "d MMM", "MMMdE": "d MMMM E", + "MMMMW": "MMMM 'ayının' W'. haftası'", "MMMMd": "d MMMM", "MMMMdE": "d MMMM E", "d": "d", diff --git a/provider/testdata/data/json/datetime/skeletons@1/gregory/und.json b/provider/testdata/data/json/datetime/skeletons@1/gregory/und.json index 8201b1a413f..3f824de436d 100644 --- a/provider/testdata/data/json/datetime/skeletons@1/gregory/und.json +++ b/provider/testdata/data/json/datetime/skeletons@1/gregory/und.json @@ -19,6 +19,7 @@ "MMM": "LLL", "MMMd": "MMM d", "MMMdE": "MMM d, E", + "MMMMW": "'week' W 'of' MMMM", "MMMMd": "MMMM d", "d": "d", "dE": "d, E", diff --git a/provider/testdata/data/testdata.postcard b/provider/testdata/data/testdata.postcard index c592f3c58307c4f796f6bca8e87eb37afa894b8f..166442430895b516c7065f576559f36918d216ac 100644 GIT binary patch delta 3222 zcmb`{dvp}l9S895Y)Ht0$-N8V5y0&1CSfrlK!Dvz2+0kbMe%`Ed;kg|AP+4?LV~=> zB9@|9<>5KK2nZsGA}UdlQ40YCtAG$hsTB~xaw3(+fNfdg48S$F~SH+aa*{BZ2K73!K|05I7*v z^^m}*V*-&nfrq{o82TT9__G36F9@8!B5=wj@m``tQIbTNN8(C~#FDlWzwaQ?%ar&a zUE+>_#Gx#S)m*B73mJYeOW=p%S;z z6so7EOC_2QlaO?Z)|N@UPCIEY&8SSn+f+kq=BMH5b!nLPNg77Pd$Bv!iymFPSQ_>s zGT4iqThpKWPI@J1580W`8%Z~|T{h0Z@AM+3Rk>4yGGgLZu%}R&yembgL8MqwIz<|ja znDSu;%pWq4+bt81^~}V=k^tVMjDZ1EjSXN>c>vpJ)tmqdbr7%b4&u`zK}5ei9mF@^ z2QlGH5Kq#Jw2?lf!*rSw&IYlyA&6-ggP2e2sD}1Z9bKhXmxAa)C3H8{C52EXL-@XB z2qRmEuqG=6Q-#o-BJ=>wQK2X{aIlB!XjwRf0ewTLpn0^6Hqgg(oGw$wjUn`={uC$; zVGun*HFSm2hJ~PLIL)S2w1d8(#Ig{w=vMjzJyjMBaTA45OQ-1I^boRVgm4?x(U0_M zO$bN+5yBXkg#qyv3KK2JBnxL-Syh1t1zSiC$BTSPwIn3|8(|ICN( z-wP+~UTE+YVEUg6@Nh!`?kebw^zFTId$17EsV^1cyeLA$q9VvEMOZLe!9P=>NtHt1 zMG7}9RxqAb7(mra6q1+m_vaL5ELYgQLcz0AVc-i2dsZn}FDfirqp0@4;eh>eL6_7xlrdoBLqIi9VRxGK>r1F#1-6v1>&bBlm@|?8h*^P$d{W zy98%;l;Ei|C0JV$L6h+jTt{E#%tl;D;9;@`t zt@Ih>qBv?o@svPKDUsaNjGEJRltjsPrBB?l(a6@Gko4O}KNq*U;^Pb$S$fD9BGr>? z045UpBH>03W|>X&@G~OiFSVk%PRNxl^wK<;qVK2?@pkz^@viZIjC1U`2-usCifmVR zC!ZY7?WE$K4|lbb3Nv%BhkH}($9Ld<1@1j?uZFt@?stFAvV(puPhQgF&x%itY?~qP zcLkkj-5R4Ao;btP+3@%cPfx}%Jp42cG7V3Ajtx)i#<_kape{Hq{JPkXr}fna(N+)p zR$T1p1or`xfl;x~*v8v=1jYlSol`F2!Z+|G^Sbn-JStjbi{p508dswuv z|6MOCjo%p0W>bzC{}VwoLR%eeCY#zVz8802W31H6;!k@0VG*yl)Qk4IzQ0_lYYmxc zzuq7&7@eIu13+c0$Z^1M;NjRY))=SSk+Hv=YVDO5#1xm&)7fIB`c%9O*efoJ7ID`U zL^H^zdcjR{xPA0TQDo?&$3-)p<&$k~w%}e@Yi0x{)dP44;IcELoLRa0BbQ8famDLh zvi(oH*~xTFVdE2#-EAST45*Hk0wL6ldwgEYrZ4L`?7O?BfNw_QD}D z-_Q$^H})eNpBlv-a9A-P|~_6EK|iYXNg@pHKFPi@hhpdPchRn~m>@WEYZiklYl> z#Yj#;vK2c`b$0wuuZ_*NnJKHB_XI=a=<;)-m9F|sB;R_(NAmP zbEbXJ=8WTh>yz=zQ+uWHfvql-rtMuIX2$8ChZPyR=4M%>Yc~kDuD)Him|Hqfl82me zOG=?u)SB8*TS}#N)Sf!f^^`_lGRa4NN~a9Uq>dDzPILohQ8sm^9O^<{sT<`|cj`es hDM%r*D39`~7Zp%%Dx@M(R7`y+OeJ>dz{sdk{{^@Rl868R delta 2481 zcma*lYj{mp8VB(IJ`qhwtd+P$Mb0@ni6B9cvp2b%mCIpjN{ym}xRgw)&mc;w?oK^A z>KPskY9q-EBdHNIaotlR;xcGO60J)OTAeAAxD2I5T$;>3={%<2W!mkO) zT7g@)1+wo6#5@$Z@kC&IgFsh*iC+gwObC{!mlAnxBqoPRB!x?yuuBYeNnGhHQ4}lD z5HE2wL85nGiOtCpi&Lc!XT1`xffBicC1wtlh#MjC(MSpBD2c%|hwjkI(Go$K5+QVt zipNNl&?%~>1=Aw1pUP?LvIwl)8i9G05y;Z)INjEcgl=}^d+g{x!j4mu?P#{hjz{Z# zb~tz2(Xqmgh8uQ#6W~Brgafa59oRI=fkHY@dX59LNKA8JE2X^UfPK0H%jgkh&2Zpr z`em*I)%3Hs9oR_;Gaaxf@f`<>C}|d-^n{+xcHlMN5(nxE9N2ipf#i-(_@+3~slo|Q zgA*hBL}JFING!~c#H!CCk=WdY1xYSc%y+?d$OT`$3(q`J7?vA_Ime>ltcybLxM;i= zAC1*2274%aSPXoVVlZk-431Laq8NDAxKVP_jdPdW@O||!H)`*=G2^Zq%jrY1=o9*q z?$Zn3x^d*b8}lBxv5Iz3IaN~)HBh^UZX}SGMo>+ljtN0Jz7smKLv?KJtize4qYw3` zU(u2z-G_bbR8b8TcytU)(~(QdsDSoSC0(ay6rHXkgf%lRZ;MDov!t zR7l6EmIBAHLXwoS}Pkd6tg2**XSO4PlOsod>F$#Z-{}1Lk+YVZeZzad>?6G&u9Y|#u>Oh!GJBB z1t%HEpJHHFj)Ass88}^KU~%`p*s!rL4!7)w-81{4=xRT#ADD<6dlK=eQxfJcO~SPM zNf>SRNj6XoUwMk3IO^LAU16C-!v{u3Pfx%wnSlisq!Izm%_>23N7|3c=stR+^=xKQm}ulkaIvG|1S#r4l2}_F=4sFjKc~$ zjwrl(j0yhAg2xr^olqF^iNcak70OO21f5pMtW+qjQfPHX;f>D}j(o0g`>aC1d4;hT z6xM#BP;t@6-Cg3O%L=tu6xw~I(7AsqT1-rZi?Xv)kwZRON;UbZ7;qsKWl?G9vmy3Hl($AFx4ROF>2`*b=Ao~GkcQU)e1%)s}DGqB=r28xvz{*%23rX`f; zV^c~OsgA;?co9!8k@sCMQrCJhj^3dyR8E)a5y=m{NTW=eN2PR~I zUaX=T^55Wvi$>8b3Vq0C=0-2Rr_ekW&s&`9d_UKzk&XPQ8TnIldVvBckXlen3Zh_Y zW#u}>&-a^`Y_f$}S}ZzPUw*6 zO&#Rf=hMSX#+#en&kJGR>>-295>w<@@&6RtwWf+cnWM#+TB#^C8H_ed{bY*exFtd~ zt2RRh{wHhjO%Z7}6p8mt`JL!y1>6;xO=+Cwrb1!g|3Ktx=JPQY$NWY!eT5>mDWdhZ zh7OVgw8jGctuA%qqGqleBBz_>g<`DL@I(}8X8uF5#On5g2=#j&I%MT*(xaKb7{v1` zo-4!5o;Srkb9}wpr?Ju(|6(E=YcXgpw&la*o(|TA} zTgnSItIGkApqW+OWw0rvJl2>#z`Qn5wz2L=>1#SrmvyMMJg8}L)>ON^rJ3Wy<>%(> zM@6P}Fj8*&AK%MtKOGuxZk{WhjYk(`ro1f!t^6qY!}B{Yvvzfn3!Cn|>3E&y!gIW| z$}?iT`Q}9tY<_!3gzt})Z)j%QS`ls?kCS&A_sX2b*0`Q>s%BNrmq9;XlGU(M6!P!77k&-BxQpiJ!QYnqnDZ?6@>CMjm EHwu3(_W%F@