Browse Source

Fixed #23049 -- Added %a and %A support to Date.strftime.

This enables the admin to display the day as locale's abbreviated/full
name if %a/%A is used in the date format.
sarahboyce 1 year ago
parent
commit
531f557f92

+ 19 - 1
django/contrib/admin/static/admin/js/calendar.js

@@ -36,6 +36,24 @@ depends on core.js for utility functions like removeChildren or quickElement
             pgettext('abbrev. month December', 'Dec')
         ],
         daysOfWeek: [
+            gettext('Sunday'),
+            gettext('Monday'),
+            gettext('Tuesday'),
+            gettext('Wednesday'),
+            gettext('Thursday'),
+            gettext('Friday'),
+            gettext('Saturday')
+        ],
+        daysOfWeekAbbrev: [
+            pgettext('abbrev. day Sunday', 'Sun'),
+            pgettext('abbrev. day Monday', 'Mon'),
+            pgettext('abbrev. day Tuesday', 'Tue'),
+            pgettext('abbrev. day Wednesday', 'Wed'),
+            pgettext('abbrev. day Thursday', 'Thur'),
+            pgettext('abbrev. day Friday', 'Fri'),
+            pgettext('abbrev. day Saturday', 'Sat')
+        ],
+        daysOfWeekInitial: [
             pgettext('one letter Sunday', 'S'),
             pgettext('one letter Monday', 'M'),
             pgettext('one letter Tuesday', 'T'),
@@ -98,7 +116,7 @@ depends on core.js for utility functions like removeChildren or quickElement
             // Draw days-of-week header
             let tableRow = quickElement('tr', tableBody);
             for (let i = 0; i < 7; i++) {
-                quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]);
+                quickElement('th', tableRow, CalendarNamespace.daysOfWeekInitial[(i + CalendarNamespace.firstDayOfWeek) % 7]);
             }
 
             const startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay();

+ 14 - 0
django/contrib/admin/static/admin/js/core.js

@@ -85,6 +85,18 @@ function findPosY(obj) {
         return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();
     };
 
+    Date.prototype.getAbbrevDayName = function() {
+        return typeof window.CalendarNamespace === "undefined"
+            ? '0' + this.getDay()
+            : window.CalendarNamespace.daysOfWeekAbbrev[this.getDay()];
+    };
+
+    Date.prototype.getFullDayName = function() {
+        return typeof window.CalendarNamespace === "undefined"
+            ? '0' + this.getDay()
+            : window.CalendarNamespace.daysOfWeek[this.getDay()];
+    };
+
     Date.prototype.getAbbrevMonthName = function() {
         return typeof window.CalendarNamespace === "undefined"
             ? this.getTwoDigitMonth()
@@ -99,6 +111,8 @@ function findPosY(obj) {
 
     Date.prototype.strftime = function(format) {
         const fields = {
+            a: this.getAbbrevDayName(),
+            A: this.getFullDayName(),
             b: this.getAbbrevMonthName(),
             B: this.getFullMonthName(),
             c: this.toString(),

+ 4 - 2
docs/ref/forms/widgets.txt

@@ -603,7 +603,8 @@ These widgets make use of the HTML elements ``input`` and ``textarea``.
 
     If no ``format`` argument is provided, the default format is the first
     format found in :setting:`DATE_INPUT_FORMATS` and respects
-    :doc:`/topics/i18n/formatting`.
+    :doc:`/topics/i18n/formatting`. ``%U``, ``%W``, and ``%j`` formats are not
+    supported by this widget.
 
 ``DateTimeInput``
 ~~~~~~~~~~~~~~~~~
@@ -622,7 +623,8 @@ These widgets make use of the HTML elements ``input`` and ``textarea``.
 
     If no ``format`` argument is provided, the default format is the first
     format found in :setting:`DATETIME_INPUT_FORMATS` and respects
-    :doc:`/topics/i18n/formatting`.
+    :doc:`/topics/i18n/formatting`. ``%U``, ``%W``, and ``%j`` formats are not
+    supported by this widget.
 
     By default, the microseconds part of the time value is always set to ``0``.
     If microseconds are required, use a subclass with the

+ 12 - 0
js_tests/admin/core.test.js

@@ -50,11 +50,23 @@ QUnit.test('Date.getFullMonthName', function(assert) {
     assert.equal(new Date(2020, 9, 26).getFullMonthName(), 'October', 'oct 26');
 });
 
+QUnit.test('Date.getAbbrevDayName', function(assert) {
+    assert.equal(new Date(2020, 0, 26).getAbbrevDayName(), 'Sun', 'jan 26 2020 is a Sunday');
+    assert.equal(new Date(2020, 9, 26).getAbbrevDayName(), 'Mon', 'oct 26 2020 is a Monday');
+});
+
+QUnit.test('Date.getFullDayName', function(assert) {
+    assert.equal(new Date(2020, 0, 26).getFullDayName(), 'Sunday', 'jan 26 2020 is a Sunday');
+    assert.equal(new Date(2020, 9, 26).getFullDayName(), 'Monday', 'oct 26 2020 is a Monday');
+});
+
 QUnit.test('Date.strftime', function(assert) {
     const date = new Date(2014, 6, 1, 11, 0, 5);
     assert.equal(date.strftime('%Y-%m-%d %H:%M:%S'), '2014-07-01 11:00:05');
     assert.equal(date.strftime('%B %d, %Y'), 'July 01, 2014');
     assert.equal(date.strftime('%b %d, %Y'), 'Jul 01, 2014');
+    assert.equal(date.strftime('%a %d %m %y'), 'Tue 01 07 14');
+    assert.equal(date.strftime('%A (day %w of week) %I %p'), 'Tuesday (day 02 of week) 11 AM');
 });
 
 QUnit.test('String.strptime', function(assert) {