branch: elpa/datetime commit 6a562be69f0893fc980df8923ba9cd34c564e5a2 Author: Paul Pogonyshev <pogonys...@gmail.com> Commit: Paul Pogonyshev <pogonys...@gmail.com>
Update support for month and weekday formatting and include narrow variants; add tests. --- datetime.el | 275 +++++++++++++++++++++++++++++---------------------- dev/HarvestData.java | 90 +++++++++-------- locale-data.extmap | Bin 367805 -> 410110 bytes test/base.el | 98 ++++++++++-------- test/format.el | 14 ++- 5 files changed, 269 insertions(+), 208 deletions(-) diff --git a/datetime.el b/datetime.el index 5b03b7fd4b..24857f37bf 100644 --- a/datetime.el +++ b/datetime.el @@ -76,8 +76,8 @@ ;; year-for-week (same as for year) ;; ;; month (NUMBER) -;; month-context-name (full | abbreviated) -;; month-standalone-name (full | abbreviated) +;; month-context-name (short | full | narrow) +;; month-standalone-name (short | full | narrow) ;; ;; week-in-year (NUMBER) ;; week-in-month (NUMBER) @@ -88,8 +88,8 @@ ;; e.g. would be 2 for 2015-09-09, because it is the second ;; Wednesday that month; ;; weekday (NUMBER) -;; weekday-context-name (full | abbreviated) -;; weekday-standalone-name (full | abbreviated) +;; weekday-context-name (short | full | narrow) +;; weekday-standalone-name (short | full | narrow) ;; ;; am-pm (full | abbreviated) ;; day-period (short | full | narrow) @@ -370,13 +370,20 @@ form: (if (<= num-repetitions 2) (cons 'month num-repetitions) (cons (if (= character ?M) 'month-context-name 'month-standalone-name) - (if (>= num-repetitions 4) 'full 'abbreviated)))) - ((or ?E ?c) - (cons (if (= character ?E) 'weekday-context-name 'weekday-standalone-name) - (if (>= num-repetitions 4) 'full 'abbreviated))) - (?e (if (<= num-repetitions 2) - (cons 'weekday num-repetitions) - (cons 'weekday-context-name (if (>= num-repetitions 4) 'full 'abbreviated)))) + (pcase num-repetitions + (3 'short) + (4 'full) + (5 'narrow) + (_ (error "Pattern character `%c' must come in 1-5 repetitions" character)))))) + ((or ?E ?c ?e) + (if (and (= character ?e) (<= num-repetitions 2)) + (cons 'weekday num-repetitions) + (cons (if (= character ?c) 'weekday-standalone-name 'weekday-context-name) + (pcase num-repetitions + ((or 1 2 3) 'short) + (4 'full) + (5 'narrow) + (_ (error "Pattern character `%c' must come in 1-5 repetitions" character)))))) (?w (cons 'week-in-year num-repetitions)) (?W (cons 'week-in-month num-repetitions)) (?D (cons 'day-in-year num-repetitions)) @@ -470,9 +477,10 @@ form: (`weekday-context-name ?E) (`weekday-standalone-name ?c)) (pcase details - (`abbreviated 3) - (`full 4) - (_ (error "Unexpected details %s" details))))) + (`short 3) + (`full 4) + (`narrow 5) + (_ (error "Unexpected details %s" details))))) (`week-in-year (cons ?w details)) (`week-in-month (cons ?W details)) (`day-in-year (cons ?D details)) @@ -721,8 +729,8 @@ to this function. (push "%s" format-parts) (push `(aref ,(datetime-locale-field locale (if (eq type 'month-context-name) - (if (eq details 'full) :month-context-names :month-context-abbr) - (if (eq details 'full) :month-standalone-names :month-standalone-abbr))) + (datetime--month-context-name-field details) + (datetime--month-standalone-name-field details))) month) format-arguments)) (`week-in-year @@ -748,8 +756,8 @@ to this function. (push "%s" format-parts) (push `(aref ,(datetime-locale-field locale (if (eq type 'weekday-context-name) - (if (eq details 'full) :weekday-context-names :weekday-context-abbr) - (if (eq details 'full) :weekday-standalone-names :weekday-standalone-abbr))) + (datetime--weekday-context-name-field details) + (datetime--weekday-standalone-name-field details))) weekday) format-arguments)) (`am-pm @@ -1147,66 +1155,63 @@ unless specified otherwise. (let* ((type (car part)) (details (cdr part))) (cons (pcase type - (`era (let ((field (datetime--era-field details))) - (when (or validating (null era-part-indices)) - (push (cons part-index field) era-part-indices)) - (datetime-locale-field locale field))) - (`year - (when (or validating (null year-part-indices)) - (push (cons part-index details) year-part-indices)) - ;; Magic number for the next loop. - 0) - (`year-for-week (error "Parsing `%s' is currently not implemented" type)) - (`month (when (or validating (null month-number-part-indices)) - (push part-index month-number-part-indices)) - 12) - (`month-context-name (let ((field (if (eq details 'abbreviated) :month-context-abbr :month-context-names))) - (when (or validating (null month-name-part-indices)) - (push (cons part-index field) month-name-part-indices)) - (datetime-locale-field locale field))) - (`month-standalone-name (let ((field (if (eq details 'abbreviated) :month-standalone-abbr :month-standalone-names))) - (when (or validating (null month-name-part-indices)) - (push (cons part-index field) month-name-part-indices)) - (datetime-locale-field locale field))) - (`week-in-year (error "Parsing `%s' is currently not implemented" type)) - (`week-in-month (error "Parsing `%s' is currently not implemented" type)) - (`day-in-month (when (or validating (null day-of-month-part-indices)) - (push part-index day-of-month-part-indices)) - 31) - (`weekday-in-month (error "Parsing `%s' is currently not implemented" type)) - (`weekday 7) - (`weekday-context-name - (datetime-locale-field locale (if (eq details 'abbreviated) :weekday-context-abbr :weekday-context-names))) - (`weekday-standalone-name - (datetime-locale-field locale (if (eq details 'abbreviated) :weekday-standalone-abbr :weekday-standalone-names))) - (`am-pm (when (or validating (null am-pm-part-indices)) - (push part-index am-pm-part-indices)) - (datetime-locale-field locale :am-pm)) - (`day-period (when (or validating (null day-period-part-indices)) - (push part-index day-period-part-indices)) - (let ((day-period-data (datetime-locale-field locale :day-periods))) - (or (plist-get day-period-data details) (plist-get day-period-data :short)))) - (`hour-0-23 (when (or validating (null hour-0-23-part-indices)) - (push part-index hour-0-23-part-indices)) - 23) - (`hour-1-24 (when (or validating (null hour-1-24-part-indices)) - (push part-index hour-1-24-part-indices)) - 24) - (`hour-am-pm-0-11 (when (or validating (null hour-am-pm-0-11-part-indices)) - (push part-index hour-am-pm-0-11-part-indices)) - 11) - (`hour-am-pm-1-12 (when (or validating (null hour-am-pm-1-12-part-indices)) - (push part-index hour-am-pm-1-12-part-indices)) - 12) - (`minute (when (or validating (null minute-part-indices)) - (push part-index minute-part-indices)) - 59) - (`second (when (or validating (null second-part-indices)) - (push part-index second-part-indices)) - 59) - (`decimal-separator (rx (or "." ","))) - (`second-fractional (push (cons part-index (expt 10.0 details)) second-fractional-part-indices) - (apply #'concat (make-list details (rx (any "0-9"))))) + (`era (let ((field (datetime--era-field details))) + (when (or validating (null era-part-indices)) + (push (cons part-index field) era-part-indices)) + (datetime-locale-field locale field))) + (`year (when (or validating (null year-part-indices)) + (push (cons part-index details) year-part-indices)) + ;; Magic number for the next loop. + 0) + (`year-for-week (error "Parsing `%s' is currently not implemented" type)) + (`month (when (or validating (null month-number-part-indices)) + (push part-index month-number-part-indices)) + 12) + (`month-context-name (let ((field (datetime--month-context-name-field details))) + (when (or validating (null month-name-part-indices)) + (push (cons part-index field) month-name-part-indices)) + (datetime-locale-field locale field))) + (`month-standalone-name (let ((field (datetime--month-standalone-name-field details))) + (when (or validating (null month-name-part-indices)) + (push (cons part-index field) month-name-part-indices)) + (datetime-locale-field locale field))) + (`week-in-year (error "Parsing `%s' is currently not implemented" type)) + (`week-in-month (error "Parsing `%s' is currently not implemented" type)) + (`day-in-month (when (or validating (null day-of-month-part-indices)) + (push part-index day-of-month-part-indices)) + 31) + (`weekday-in-month (error "Parsing `%s' is currently not implemented" type)) + (`weekday 7) + (`weekday-context-name (datetime-locale-field locale (datetime--weekday-context-name-field details))) + (`weekday-standalone-name (datetime-locale-field locale (datetime--weekday-standalone-name-field details))) + (`am-pm (when (or validating (null am-pm-part-indices)) + (push part-index am-pm-part-indices)) + (datetime-locale-field locale :am-pm)) + (`day-period (when (or validating (null day-period-part-indices)) + (push part-index day-period-part-indices)) + (let ((day-period-data (datetime-locale-field locale :day-periods))) + (or (plist-get day-period-data details) (plist-get day-period-data :short)))) + (`hour-0-23 (when (or validating (null hour-0-23-part-indices)) + (push part-index hour-0-23-part-indices)) + 23) + (`hour-1-24 (when (or validating (null hour-1-24-part-indices)) + (push part-index hour-1-24-part-indices)) + 24) + (`hour-am-pm-0-11 (when (or validating (null hour-am-pm-0-11-part-indices)) + (push part-index hour-am-pm-0-11-part-indices)) + 11) + (`hour-am-pm-1-12 (when (or validating (null hour-am-pm-1-12-part-indices)) + (push part-index hour-am-pm-1-12-part-indices)) + 12) + (`minute (when (or validating (null minute-part-indices)) + (push part-index minute-part-indices)) + 59) + (`second (when (or validating (null second-part-indices)) + (push part-index second-part-indices)) + 59) + (`decimal-separator (rx (or "." ","))) + (`second-fractional (push (cons part-index (expt 10.0 details)) second-fractional-part-indices) + (apply #'concat (make-list details (rx (any "0-9"))))) (`timezone (pcase details ((or `abbreviated `full) @@ -1596,8 +1601,7 @@ specified otherwise. (let* ((type (car part)) (details (cdr part)) (regexp (pcase type - (`era - (datetime-locale-field locale (datetime--era-field details))) + (`era (datetime-locale-field locale (datetime--era-field details))) ((or `year `year-for-week) (cond ((and (plist-get options :only-4-digit-years) (eq details 4)) (rx (= 4 (any "0-9")))) @@ -1607,34 +1611,27 @@ specified otherwise. (rx (any "0-9") (1+ (any "0-9")))) (t (format "[0-9]\\{%d\\}[0-9]+" (1- details))))) - (`month 12) - (`month-context-name - (datetime-locale-field locale (if (eq details 'abbreviated) :month-context-abbr :month-context-names))) - (`month-standalone-name - (datetime-locale-field locale (if (eq details 'abbreviated) :month-standalone-abbr :month-standalone-names))) - (`week-in-year 53) - (`week-in-month 5) - (`day-in-month 31) - (`weekday-in-month 5) - (`weekday 7) - (`weekday-context-name - (datetime-locale-field locale (if (eq details 'abbreviated) :weekday-context-abbr :weekday-context-names))) - (`weekday-standalone-name - (datetime-locale-field locale (if (eq details 'abbreviated) :weekday-standalone-abbr :weekday-standalone-names))) - (`am-pm - (datetime-locale-field locale :am-pm)) - (`day-period - (let ((day-period-data (datetime-locale-field locale :day-periods))) - (or (plist-get day-period-data details) (plist-get day-period-data :short)))) - (`hour-0-23 23) - (`hour-1-24 24) - (`hour-am-pm-0-11 11) - (`hour-am-pm-1-12 12) - (`minute 59) - (`second 59) - (`decimal-separator (rx (or "." ","))) - (`second-fractional - (apply #'concat (make-list details (rx (any "0-9"))))) + (`month 12) + (`month-context-name (datetime-locale-field locale (datetime--month-context-name-field details))) + (`month-standalone-name (datetime-locale-field locale (datetime--month-standalone-name-field details))) + (`week-in-year 53) + (`week-in-month 5) + (`day-in-month 31) + (`weekday-in-month 5) + (`weekday 7) + (`weekday-context-name (datetime-locale-field locale (datetime--weekday-context-name-field details))) + (`weekday-standalone-name (datetime-locale-field locale (datetime--weekday-standalone-name-field details))) + (`am-pm (datetime-locale-field locale :am-pm)) + (`day-period (let ((day-period-data (datetime-locale-field locale :day-periods))) + (or (plist-get day-period-data details) (plist-get day-period-data :short)))) + (`hour-0-23 23) + (`hour-1-24 24) + (`hour-am-pm-0-11 11) + (`hour-am-pm-1-12 12) + (`minute 59) + (`second 59) + (`decimal-separator (rx (or "." ","))) + (`second-fractional (apply #'concat (make-list details (rx (any "0-9"))))) (`timezone (pcase details ((or `abbreviated `full) @@ -1920,33 +1917,47 @@ separated by a space, for quite a few locales it is different." ;; See `datetime--locale-extmap' for description of fallbacks. (pcase field ((or :eras-full :eras-narrow) (plist-get locale-data :eras-short)) - (:month-standalone-abbr (plist-get locale-data :month-context-abbr)) - (:month-standalone-names (plist-get locale-data :month-context-names)) - (:weekday-standalone-abbr (plist-get locale-data :weekday-context-abbr)) - (:weekday-standalone-names (plist-get locale-data :weekday-context-names))))) + (:month-standalone-short (plist-get locale-data :month-context-short)) + (:month-standalone-full (plist-get locale-data :month-context-full)) + (:month-standalone-narrow (plist-get locale-data :month-context-narrow)) + (:weekday-standalone-short (plist-get locale-data :weekday-context-short)) + (:weekday-standalone-full (plist-get locale-data :weekday-context-full)) + (:weekday-standalone-narrow (plist-get locale-data :weekday-context-narrow))))) (defun datetime-locale-field (locale field) "Get a FIELD of data for the LOCALE. Supported fields: :decimal-separator - :eras-short (also old alias :eras) + :eras-short (alias: :eras) :eras-full :eras-narrow - :month-context-abbr - :month-context-names + :month-context-short (alias: :month-context-abbr) + :month-context-full (alias: :month-context-names) + :month-context-narrow :weekday-context-abbr :weekday-context-names - :month-standalone-abbr - :month-standalone-names + :month-standalone-short (alias: :month-standalone-abbr) + :month-standalone-full (alias: :month-standalone-names) + :month-standalone-narrow :weekday-standalone-abbr :weekday-standalone-names :am-pm" ;; Additionally `:day-periods', `:date-patterns', `:time-patterns' and ;; `:date-time-pattern-rule' are supported for internal use. (let ((data (extmap-get datetime--locale-extmap locale t))) - (pcase field - (:eras (setf field :eras-short))) + ;; Resolve aliases, mostly for compatibility with older versions. + (setf field (pcase field + (:eras :eras-short) + (:month-context-abbr :month-context-short) + (:month-context-names :month-context-full) + (:month-standalone-abbr :month-standalone-short) + (:month-standalone-names :month-standalone-full) + (:weekday-context-abbr :weekday-context-short) + (:weekday-context-names :weekday-context-full) + (:weekday-standalone-abbr :weekday-standalone-short) + (:weekday-standalone-names :weekday-standalone-full) + (_ field))) (or (datetime--do-get-locale-field data field) (let ((parent (plist-get data :parent))) (when parent @@ -1962,6 +1973,30 @@ Supported fields: (`full :eras-full) (`narrow :eras-narrow))) +(defun datetime--month-context-name-field (details) + (pcase-exhaustive details + (`short :month-context-short) + (`full :month-context-full) + (`narrow :month-context-narrow))) + +(defun datetime--month-standalone-name-field (details) + (pcase-exhaustive details + (`short :month-standalone-short) + (`full :month-standalone-full) + (`narrow :month-standalone-narrow))) + +(defun datetime--weekday-context-name-field (details) + (pcase-exhaustive details + (`short :weekday-context-short) + (`full :weekday-context-full) + (`narrow :weekday-context-narrow))) + +(defun datetime--weekday-standalone-name-field (details) + (pcase-exhaustive details + (`short :weekday-standalone-short) + (`full :weekday-standalone-full) + (`narrow :weekday-standalone-narrow))) + (defun datetime-locale-timezone-name (locale timezone dst &optional full) "Get name of TIMEZONE in given LOCALE. For timezones that don't have daylight saving time, parameter DST @@ -1999,7 +2034,7 @@ create based on locales `datetime' knows about. Note that this database doesn't include timezone names. See `datetime-timezone-name-database-version'." - 7) + 8) (defun datetime-timezone-database-version () "Return timezone database version, a simple integer. diff --git a/dev/HarvestData.java b/dev/HarvestData.java index 9c082e4487..0cb29c6ac8 100644 --- a/dev/HarvestData.java +++ b/dev/HarvestData.java @@ -74,20 +74,24 @@ public class HarvestData Map <String, String> map = new LinkedHashMap <> (); data.put (locale, map); - map.put (":decimal-separator", String.format ("?%c", DecimalStyle.of (locale).getDecimalSeparator ())); - map.put (":eras-short", toLispVector (getNames (locale, ChronoField.ERA, "G", 0, 1))); - map.put (":eras-full", toLispVector (getNames (locale, ChronoField.ERA, "GGGG", 0, 1))); - map.put (":eras-narrow", toLispVector (getNames (locale, ChronoField.ERA, "GGGGG", 0, 1))); - map.put (":month-context-abbr", toLispVector (getNames (locale, ChronoField.MONTH_OF_YEAR, "MMM", 1, 12))); - map.put (":month-context-names", toLispVector (getNames (locale, ChronoField.MONTH_OF_YEAR, "MMMM", 1, 12))); - map.put (":weekday-context-abbr", toLispVector (getNames (locale, ChronoField.DAY_OF_WEEK, "EEE", 1, 7))); - map.put (":weekday-context-names", toLispVector (getNames (locale, ChronoField.DAY_OF_WEEK, "EEEE", 1, 7))); - map.put (":month-standalone-abbr", toLispVector (getNames (locale, ChronoField.MONTH_OF_YEAR, "LLL", 1, 12))); - map.put (":month-standalone-names", toLispVector (getNames (locale, ChronoField.MONTH_OF_YEAR, "LLLL", 1, 12))); - map.put (":weekday-standalone-abbr", toLispVector (getNames (locale, ChronoField.DAY_OF_WEEK, "ccc", 1, 7))); - map.put (":weekday-standalone-names", toLispVector (getNames (locale, ChronoField.DAY_OF_WEEK, "cccc", 1, 7))); - map.put (":am-pm", toLispVector (getNames (locale, ChronoField.AMPM_OF_DAY, "a", 0, 1))); - map.put (":day-periods", findDayPeriodData (locale)); + map.put (":decimal-separator", String.format ("?%c", DecimalStyle.of (locale).getDecimalSeparator ())); + map.put (":eras-short", toLispVector (getNames (locale, ChronoField.ERA, "G", 0, 1))); + map.put (":eras-full", toLispVector (getNames (locale, ChronoField.ERA, "GGGG", 0, 1))); + map.put (":eras-narrow", toLispVector (getNames (locale, ChronoField.ERA, "GGGGG", 0, 1))); + map.put (":month-context-short", toLispVector (getNames (locale, ChronoField.MONTH_OF_YEAR, "MMM", 1, 12))); + map.put (":month-context-full", toLispVector (getNames (locale, ChronoField.MONTH_OF_YEAR, "MMMM", 1, 12))); + map.put (":month-context-narrow", toLispVector (getNames (locale, ChronoField.MONTH_OF_YEAR, "MMMMM", 1, 12))); + map.put (":weekday-context-short", toLispVector (getNames (locale, ChronoField.DAY_OF_WEEK, "EEE", 1, 7))); + map.put (":weekday-context-full", toLispVector (getNames (locale, ChronoField.DAY_OF_WEEK, "EEEE", 1, 7))); + map.put (":weekday-context-narrow", toLispVector (getNames (locale, ChronoField.DAY_OF_WEEK, "EEEEE", 1, 7))); + map.put (":month-standalone-short", toLispVector (getNames (locale, ChronoField.MONTH_OF_YEAR, "LLL", 1, 12))); + map.put (":month-standalone-full", toLispVector (getNames (locale, ChronoField.MONTH_OF_YEAR, "LLLL", 1, 12))); + map.put (":month-standalone-narrow", toLispVector (getNames (locale, ChronoField.MONTH_OF_YEAR, "LLLLL", 1, 12))); + map.put (":weekday-standalone-short", toLispVector (getNames (locale, ChronoField.DAY_OF_WEEK, "ccc", 1, 7))); + map.put (":weekday-standalone-full", toLispVector (getNames (locale, ChronoField.DAY_OF_WEEK, "cccc", 1, 7))); + map.put (":weekday-standalone-narrow", toLispVector (getNames (locale, ChronoField.DAY_OF_WEEK, "ccccc", 1, 7))); + map.put (":am-pm", toLispVector (getNames (locale, ChronoField.AMPM_OF_DAY, "a", 0, 1))); + map.put (":day-periods", findDayPeriodData (locale)); Map <String, String> date_patterns = toPatternPlist ((style) -> DateTimeFormatterBuilder.getLocalizedDateTimePattern (style, null, chronology, locale)); Map <String, String> time_patterns = toPatternPlist ((style) -> DateTimeFormatterBuilder.getLocalizedDateTimePattern (null, style, chronology, locale)); @@ -241,16 +245,18 @@ public class HarvestData } - private static Map <String, String> LOCALE_FALLBACK_KEYS = Map.of (":eras-full", ":eras-short", - ":eras-narrow", ":eras-short", - ":month-standalone-abbr", ":month-context-abbr", - ":month-standalone-names", ":month-context-names", - ":weekday-standalone-abbr", ":weekday-context-abbr", - ":weekday-standalone-names", ":weekday-context-names"); - private static Map <String, String> LOCALE_DEFAULT_VALUES = Map.of (":decimal-separator", "?.", - ":eras", ENGLISH_ERAS, - ":am-pm", ENGLISH_AM_PM, - ":date-time-pattern-rule", "(t . \" \")"); + private static Map <String, String> LOCALE_FALLBACK_KEYS = Map.of (":eras-full", ":eras-short", + ":eras-narrow", ":eras-short", + ":month-standalone-short", ":month-context-short", + ":month-standalone-full", ":month-context-full", + ":month-standalone-narrow", ":month-context-narrow", + ":weekday-standalone-short", ":weekday-context-short", + ":weekday-standalone-full", ":weekday-context-full", + ":weekday-standalone-narrow", ":weekday-context-narrow"); + private static Map <String, String> LOCALE_DEFAULT_VALUES = Map.of (":decimal-separator", "?.", + ":eras", ENGLISH_ERAS, + ":am-pm", ENGLISH_AM_PM, + ":date-time-pattern-rule", "(t . \" \")"); protected static void removeUnnecessaryLocaleData (Map <Locale, Map <String, String>> data, Locale locale) { @@ -678,40 +684,40 @@ public class HarvestData { var xx = Locale.forLanguageTag ("xx"); var xx_yy = Locale.forLanguageTag ("xx-YY"); - var data1 = Map.of (xx, modifiableMap (":month-context-abbr", "1", ":month-standalone-abbr", "1"), - xx_yy, modifiableMap (":month-context-abbr", "1", ":month-standalone-abbr", "1")); + var data1 = Map.of (xx, modifiableMap (":month-context-short", "1", ":month-standalone-short", "1"), + xx_yy, modifiableMap (":month-context-short", "1", ":month-standalone-short", "1")); removeUnnecessaryLocaleData (data1, xx_yy); - assertEquals (data1, Map.of (xx, modifiableMap (":month-context-abbr", "1"), + assertEquals (data1, Map.of (xx, modifiableMap (":month-context-short", "1"), xx_yy, modifiableMap (":parent", "xx"))); - var data2 = Map.of (xx, modifiableMap (":month-context-abbr", "1", ":month-standalone-abbr", "2"), - xx_yy, modifiableMap (":month-context-abbr", "1", ":month-standalone-abbr", "2")); + var data2 = Map.of (xx, modifiableMap (":month-context-short", "1", ":month-standalone-short", "2"), + xx_yy, modifiableMap (":month-context-short", "1", ":month-standalone-short", "2")); removeUnnecessaryLocaleData (data2, xx_yy); - assertEquals (data2, Map.of (xx, modifiableMap (":month-context-abbr", "1", ":month-standalone-abbr", "2"), + assertEquals (data2, Map.of (xx, modifiableMap (":month-context-short", "1", ":month-standalone-short", "2"), xx_yy, modifiableMap (":parent", "xx"))); - var data3 = Map.of (xx, modifiableMap (":month-context-abbr", "1", ":month-standalone-abbr", "2"), - xx_yy, modifiableMap (":month-context-abbr", "1", ":month-standalone-abbr", "3")); + var data3 = Map.of (xx, modifiableMap (":month-context-short", "1", ":month-standalone-short", "2"), + xx_yy, modifiableMap (":month-context-short", "1", ":month-standalone-short", "3")); removeUnnecessaryLocaleData (data3, xx_yy); - assertEquals (data3, Map.of (xx, modifiableMap (":month-context-abbr", "1", ":month-standalone-abbr", "2"), - xx_yy, modifiableMap (":parent", "xx", ":month-standalone-abbr", "3"))); + assertEquals (data3, Map.of (xx, modifiableMap (":month-context-short", "1", ":month-standalone-short", "2"), + xx_yy, modifiableMap (":parent", "xx", ":month-standalone-short", "3"))); - var data4 = Map.of (xx, modifiableMap (":month-standalone-abbr", "2"), - xx_yy, modifiableMap (":month-context-abbr", "1", ":month-standalone-abbr", "2")); + var data4 = Map.of (xx, modifiableMap (":month-standalone-short", "2"), + xx_yy, modifiableMap (":month-context-short", "1", ":month-standalone-short", "2")); removeUnnecessaryLocaleData (data4, xx_yy); - assertEquals (data4, Map.of (xx, modifiableMap (":month-standalone-abbr", "2"), - xx_yy, modifiableMap (":parent", "xx", ":month-context-abbr", "1", ":month-standalone-abbr", "2"))); + assertEquals (data4, Map.of (xx, modifiableMap (":month-standalone-short", "2"), + xx_yy, modifiableMap (":parent", "xx", ":month-context-short", "1", ":month-standalone-short", "2"))); - var data5 = Map.of (xx, modifiableMap (":month-context-abbr", "1", ":month-standalone-abbr", "2"), - xx_yy, modifiableMap (":month-context-abbr", "1", ":month-standalone-abbr", "1")); + var data5 = Map.of (xx, modifiableMap (":month-context-short", "1", ":month-standalone-short", "2"), + xx_yy, modifiableMap (":month-context-short", "1", ":month-standalone-short", "1")); removeUnnecessaryLocaleData (data5, xx_yy); - assertEquals (data5, Map.of (xx, modifiableMap (":month-context-abbr", "1", ":month-standalone-abbr", "2"), - xx_yy, modifiableMap (":parent", "xx", ":month-standalone-abbr", "1"))); + assertEquals (data5, Map.of (xx, modifiableMap (":month-context-short", "1", ":month-standalone-short", "2"), + xx_yy, modifiableMap (":parent", "xx", ":month-standalone-short", "1"))); } diff --git a/locale-data.extmap b/locale-data.extmap index 973f236528..1744cdf8cc 100644 Binary files a/locale-data.extmap and b/locale-data.extmap differ diff --git a/test/base.el b/test/base.el index 340c1f0319..fcb0de0829 100644 --- a/test/base.el +++ b/test/base.el @@ -146,53 +146,65 @@ (ert-deftest datetime-locale-database-sanity () (dolist (locale (datetime-list-locales t)) - (let ((decimal-separator (datetime-locale-field locale :decimal-separator)) - (eras-short (datetime-locale-field locale :eras-short)) - (eras-full (datetime-locale-field locale :eras-full)) - (eras-narrow (datetime-locale-field locale :eras-narrow)) - (month-context-abbr (datetime-locale-field locale :month-context-abbr)) - (month-context-names (datetime-locale-field locale :month-context-names)) - (weekday-context-abbr (datetime-locale-field locale :weekday-context-abbr)) - (weekday-context-names (datetime-locale-field locale :weekday-context-names)) - (month-standalone-abbr (datetime-locale-field locale :month-standalone-abbr)) - (month-standalone-names (datetime-locale-field locale :month-standalone-names)) - (weekday-standalone-abbr (datetime-locale-field locale :weekday-standalone-abbr)) - (weekday-standalone-names (datetime-locale-field locale :weekday-standalone-names)) - (am-pm (datetime-locale-field locale :am-pm))) + (let ((decimal-separator (datetime-locale-field locale :decimal-separator)) + (eras-short (datetime-locale-field locale :eras-short)) + (eras-full (datetime-locale-field locale :eras-full)) + (eras-narrow (datetime-locale-field locale :eras-narrow)) + (month-context-short (datetime-locale-field locale :month-context-short)) + (month-context-full (datetime-locale-field locale :month-context-full)) + (month-context-narrow (datetime-locale-field locale :month-context-narrow)) + (weekday-context-short (datetime-locale-field locale :weekday-context-short)) + (weekday-context-full (datetime-locale-field locale :weekday-context-full)) + (weekday-context-narrow (datetime-locale-field locale :weekday-context-narrow)) + (month-standalone-short (datetime-locale-field locale :month-standalone-short)) + (month-standalone-full (datetime-locale-field locale :month-standalone-full)) + (month-standalone-narrow (datetime-locale-field locale :month-standalone-narrow)) + (weekday-standalone-short (datetime-locale-field locale :weekday-standalone-short)) + (weekday-standalone-full (datetime-locale-field locale :weekday-standalone-full)) + (weekday-standalone-narrow (datetime-locale-field locale :weekday-standalone-narrow)) + (am-pm (datetime-locale-field locale :am-pm))) (ert-info ((format "\ -locale = %S -decimal-separator = %S -eras-short = %S -eras-full = %S -eras-narrow = %S -month-context-abbr = %S -month-context-names = %S -weekday-context-abbr = %S -weekday-context-names = %S -month-standalone-abbr = %S -month-standalone-names = %S -weekday-standalone-abbr = %S -weekday-standalone-names = %S -am-pm = %S" +locale = %S +decimal-separator = %S +eras-short = %S +eras-full = %S +eras-narrow = %S +month-context-short = %S +month-context-full = %S +month-context-narrow = %S +weekday-context-short = %S +weekday-context-full = %S +weekday-context-narrow = %S +month-standalone-short = %S +month-standalone-full = %S +month-standalone-narrow = %S +weekday-standalone-short = %S +weekday-standalone-full = %S +weekday-standalone-narrow = %S +am-pm = %S" locale decimal-separator eras-short eras-full eras-narrow - month-context-abbr month-context-names - weekday-context-abbr weekday-context-names - month-standalone-abbr month-standalone-names - weekday-standalone-abbr weekday-standalone-names + month-context-short month-context-full month-context-narrow + weekday-context-short weekday-context-full weekday-context-narrow + month-standalone-short month-standalone-full month-standalone-narrow + weekday-standalone-short weekday-standalone-full weekday-standalone-narrow am-pm)) (should (memq decimal-separator '(?. ?, ?٫))) - (dolist (entry `((,eras-short 2) - (,eras-full 2) - (,eras-narrow 2) - (,month-context-abbr 12) - (,month-context-names 12) - (,weekday-context-abbr 7) - (,weekday-context-names 7) - (,month-standalone-abbr 12) - (,month-standalone-names 12) - (,weekday-standalone-abbr 7) - (,weekday-standalone-names 7) - (,am-pm 2))) + (dolist (entry `((,eras-short 2) + (,eras-full 2) + (,eras-narrow 2) + (,month-context-short 12) + (,month-context-full 12) + (,month-context-narrow 12) + (,weekday-context-short 7) + (,weekday-context-full 7) + (,weekday-context-narrow 7) + (,month-standalone-short 12) + (,month-standalone-full 12) + (,month-standalone-narrow 12) + (,weekday-standalone-short 7) + (,weekday-standalone-full 7) + (,weekday-standalone-narrow 7) + (,am-pm 2))) (let ((value (car entry)) (length (cadr entry))) (should (and (vectorp value) (= (length value) length))) diff --git a/test/format.el b/test/format.el index 59c608d475..b021b53541 100644 --- a/test/format.el +++ b/test/format.el @@ -175,15 +175,23 @@ ;; Loop over all supported Java specifiers and make sure we produce the same results for ;; them as the Java benchmark. To make it somewhat faster, combine multiple elements ;; into one pattern where easily possible, - (dolist (entry '(("G GG GGG GGGG GGGGG" era t))) ; Java (as of 17) allows at most five repetitions. + (dolist (entry '(("G GG GGG GGGG GGGGG" era t) + ("y yy yyy yyyy" year nil) + ("M MM MMM MMMM MMMMM / L LL LLL LLLL LLLLL" month t) + ;; FIXME: fails for 'c', 'e' and 'ee' (weekday _number_) currently. + ;; 'cc' (exactly two repetitions) is not supported. + ("E EE EEE EEEE EEEEE / ccc cccc ccccc / eee eeee eeeee" weekday t))) (let ((pattern (nth 0 entry)) (unit (nth 1 entry)) (locale-specific (nth 2 entry))) (dolist (locale (if locale-specific (datetime-list-locales t) '(en))) (datetime--test-set-up-formatter 'UTC locale pattern (datetime--test-formatter (pcase unit - (`era '(0 -100000000000)) - (_ (error "Unknown unit `%s'" unit))))))))) + (`era '(0 -100000000000)) + (`year (mapcar (lambda (n) (* (- n 50) 1000000000)) (number-sequence 0 100))) + (`month (mapcar (lambda (n) (* n 86400 31)) (number-sequence 0 11))) + (`weekday (mapcar (lambda (n) (* n 86400)) (number-sequence 0 6))) + (_ (error "Unknown unit `%s'" unit))))))))) (provide 'test/format)