From 531f557f9238b8f2e5032e569cf36f0c05bb4043 Mon Sep 17 00:00:00 2001 From: sarahboyce Date: Thu, 8 Jun 2023 09:51:12 +0200 Subject: [PATCH] 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. --- .../contrib/admin/static/admin/js/calendar.js | 20 ++++++++++++++++++- django/contrib/admin/static/admin/js/core.js | 14 +++++++++++++ docs/ref/forms/widgets.txt | 6 ++++-- js_tests/admin/core.test.js | 12 +++++++++++ 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/django/contrib/admin/static/admin/js/calendar.js b/django/contrib/admin/static/admin/js/calendar.js index a62d10a759..776310f75b 100644 --- a/django/contrib/admin/static/admin/js/calendar.js +++ b/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(); diff --git a/django/contrib/admin/static/admin/js/core.js b/django/contrib/admin/static/admin/js/core.js index 0344a13f42..10504d4a84 100644 --- a/django/contrib/admin/static/admin/js/core.js +++ b/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(), diff --git a/docs/ref/forms/widgets.txt b/docs/ref/forms/widgets.txt index 1fbd5ad4a0..efff81ddbc 100644 --- a/docs/ref/forms/widgets.txt +++ b/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 diff --git a/js_tests/admin/core.test.js b/js_tests/admin/core.test.js index ea780d01d0..c549ad99c9 100644 --- a/js_tests/admin/core.test.js +++ b/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) {