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)


Reply via email to