From cd4a6834e4010e74fb4b07eb02f2286578a09803 Mon Sep 17 00:00:00 2001
From: Mathias Brodala <mbrodala@pagemachine.de>
Date: Thu, 28 Mar 2024 10:25:17 +0100
Subject: [PATCH] [TASK] Use ISO 8601 format for date rendering

Resolves: #103496
Releases: main, 12.4
Change-Id: I688540c91e85d28eec1951305d63028efa27eb82
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83617
Tested-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Simon Schaufelberger <simonschaufi+typo3@gmail.com>
Reviewed-by: Benni Mack <benni@typo3.org>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Simon Schaufelberger <simonschaufi+typo3@gmail.com>
Tested-by: Benni Mack <benni@typo3.org>
Tested-by: core-ci <typo3@b13.com>
---
 .../RecordList/DownloadRecordListTest.php     |  2 +-
 .../Controller/File/FileControllerTest.php    |  2 +-
 .../Form/Element/AbstractFormElementTest.php  |  2 +-
 .../FormDataProvider/TcaRecordTitleTest.php   | 10 ++++----
 .../Tests/Unit/Utility/BackendUtilityTest.php | 14 +++++------
 .../Configuration/DefaultConfiguration.php    |  2 +-
 .../DefaultConfigurationDescription.yaml      |  4 +--
 ...t-103496-ISOFormatUsedForDateRendering.rst | 25 +++++++++++++++++++
 .../Provider/RecoveryCodesProviderTest.php    |  4 +--
 .../Mfa/Provider/TotpProviderTest.php         |  4 +--
 10 files changed, 47 insertions(+), 22 deletions(-)
 create mode 100644 typo3/sysext/core/Documentation/Changelog/12.4.x/Important-103496-ISOFormatUsedForDateRendering.rst

diff --git a/typo3/sysext/backend/Tests/Functional/RecordList/DownloadRecordListTest.php b/typo3/sysext/backend/Tests/Functional/RecordList/DownloadRecordListTest.php
index 80496ca4a81e..089ee80da4d4 100644
--- a/typo3/sysext/backend/Tests/Functional/RecordList/DownloadRecordListTest.php
+++ b/typo3/sysext/backend/Tests/Functional/RecordList/DownloadRecordListTest.php
@@ -68,7 +68,7 @@ final class DownloadRecordListTest extends FunctionalTestCase
                 'email' => '',
                 'realName' => '',
                 'admin' => 'Yes',
-                'crdate' => '22-04-13 14:55',
+                'crdate' => '2013-04-22 14:55',
             ],
         ], $this->prepareRecordsForDbCompatAssertions($result));
     }
diff --git a/typo3/sysext/backend/Tests/Unit/Controller/File/FileControllerTest.php b/typo3/sysext/backend/Tests/Unit/Controller/File/FileControllerTest.php
index 6ea18c01d081..bb19e7da740b 100644
--- a/typo3/sysext/backend/Tests/Unit/Controller/File/FileControllerTest.php
+++ b/typo3/sysext/backend/Tests/Unit/Controller/File/FileControllerTest.php
@@ -83,7 +83,7 @@ final class FileControllerTest extends UnitTestCase
         self::assertSame(
             [
                 'id' => 'foo',
-                'date' => '29-11-73',
+                'date' => '1973-11-29',
                 'icon' => '',
                 'thumbUrl' => '',
                 'path' => '',
diff --git a/typo3/sysext/backend/Tests/Unit/Form/Element/AbstractFormElementTest.php b/typo3/sysext/backend/Tests/Unit/Form/Element/AbstractFormElementTest.php
index f4100ac81e75..c771ad66dc5d 100644
--- a/typo3/sysext/backend/Tests/Unit/Form/Element/AbstractFormElementTest.php
+++ b/typo3/sysext/backend/Tests/Unit/Form/Element/AbstractFormElementTest.php
@@ -82,7 +82,7 @@ final class AbstractFormElementTest extends UnitTestCase
                     'format' => 'datetime',
                 ],
                 '1412358894',
-                '03-10-14 17:54',
+                '2014-10-03 17:54',
             ],
             'format to datetime with empty value' => [
                 [
diff --git a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaRecordTitleTest.php b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaRecordTitleTest.php
index f2ceb48aeb8d..cccfb89ed628 100644
--- a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaRecordTitleTest.php
+++ b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaRecordTitleTest.php
@@ -265,7 +265,7 @@ final class TcaRecordTitleTest extends UnitTestCase
                     'format' => 'date',
                 ],
                 '978307261',
-                '01-01-01 (-7 days)',
+                '2001-01-01 (-7 days)',
             ],
             'date (dbType: date)' => [
                 [
@@ -274,7 +274,7 @@ final class TcaRecordTitleTest extends UnitTestCase
                     'dbType' => 'date',
                 ],
                 '2001-01-01',
-                '01-01-01 (-7 days)',
+                '2001-01-01 (-7 days)',
             ],
             'date (disableAgeDisplay: TRUE)' => [
                 [
@@ -283,7 +283,7 @@ final class TcaRecordTitleTest extends UnitTestCase
                     'disableAgeDisplay' => true,
                 ],
                 '978307261',
-                '01-01-01',
+                '2001-01-01',
             ],
             'time' => [
                 [
@@ -325,7 +325,7 @@ final class TcaRecordTitleTest extends UnitTestCase
                     'dbType' => 'date',
                 ],
                 '978307261',
-                '01-01-01 00:01',
+                '2001-01-01 00:01',
             ],
             'datetime (dbType: datetime)' => [
                 [
@@ -333,7 +333,7 @@ final class TcaRecordTitleTest extends UnitTestCase
                     'dbType' => 'datetime',
                 ],
                 '2014-12-31 23:59:59',
-                '31-12-14 23:59',
+                '2014-12-31 23:59',
             ],
         ];
     }
diff --git a/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php b/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php
index eded201c4bbb..3e4cfe4cb3ac 100644
--- a/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php
+++ b/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php
@@ -548,7 +548,7 @@ final class BackendUtilityTest extends UnitTestCase
                 ],
             ],
         ];
-        self::assertSame('28-08-15 (-2 days)', BackendUtility::getProcessedValue('tt_content', 'date', mktime(0, 0, 0, 8, 28, 2015)));
+        self::assertSame('2015-08-28 (-2 days)', BackendUtility::getProcessedValue('tt_content', 'date', mktime(0, 0, 0, 8, 28, 2015)));
     }
 
     public static function inputTypeDateDisplayOptions(): array
@@ -556,19 +556,19 @@ final class BackendUtilityTest extends UnitTestCase
         return [
             'typeSafe Setting' => [
                 true,
-                '28-08-15',
+                '2015-08-28',
             ],
             'non typesafe setting' => [
                 1,
-                '28-08-15',
+                '2015-08-28',
             ],
             'setting disabled typesafe' => [
                 false,
-                '28-08-15 (-2 days)',
+                '2015-08-28 (-2 days)',
             ],
             'setting disabled not typesafe' => [
                 0,
-                '28-08-15 (-2 days)',
+                '2015-08-28 (-2 days)',
             ],
         ];
     }
@@ -1106,8 +1106,8 @@ final class BackendUtilityTest extends UnitTestCase
         $GLOBALS['LANG'] = $languageServiceMock;
         $GLOBALS['EXEC_TIME'] = mktime(0, 0, 0, 3, 23, 2016);
 
-        self::assertSame('24-03-16 00:00 (-1 day)', BackendUtility::dateTimeAge($GLOBALS['EXEC_TIME'] + 86400));
-        self::assertSame('24-03-16 (-1 day)', BackendUtility::dateTimeAge($GLOBALS['EXEC_TIME'] + 86400, 1, 'date'));
+        self::assertSame('2016-03-24 00:00 (-1 day)', BackendUtility::dateTimeAge($GLOBALS['EXEC_TIME'] + 86400));
+        self::assertSame('2016-03-24 (-1 day)', BackendUtility::dateTimeAge($GLOBALS['EXEC_TIME'] + 86400, 1, 'date'));
     }
 
     #[Test]
diff --git a/typo3/sysext/core/Configuration/DefaultConfiguration.php b/typo3/sysext/core/Configuration/DefaultConfiguration.php
index a663aa6c5404..0254ef963301 100644
--- a/typo3/sysext/core/Configuration/DefaultConfiguration.php
+++ b/typo3/sysext/core/Configuration/DefaultConfiguration.php
@@ -92,7 +92,7 @@ return [
         'cookieDomain' => '',
         'trustedHostsPattern' => 'SERVER_NAME',
         'devIPmask' => '127.0.0.1,::1',
-        'ddmmyy' => 'd-m-y',
+        'ddmmyy' => 'Y-m-d',
         'hhmm' => 'H:i',
         'loginCopyrightWarrantyProvider' => '',
         'loginCopyrightWarrantyURL' => '',
diff --git a/typo3/sysext/core/Configuration/DefaultConfigurationDescription.yaml b/typo3/sysext/core/Configuration/DefaultConfigurationDescription.yaml
index 37ededbbf3d0..38d14b099f4b 100644
--- a/typo3/sysext/core/Configuration/DefaultConfigurationDescription.yaml
+++ b/typo3/sysext/core/Configuration/DefaultConfigurationDescription.yaml
@@ -75,10 +75,10 @@ SYS:
             description: 'Defines a list of IP addresses which will allow development-output to display. The debug() function will use this as a filter. See the function <code>\TYPO3\CMS\Core\Utility\GeneralUtility::cmpIP()</code> for details on syntax. Setting this to blank value will deny all. Setting to "*" will allow all.'
         ddmmyy:
             type: text
-            description: 'Format of Day-Month-Year - see PHP-function <a href="https://php.net/date" target="_blank" rel="noreferrer">date()</a>'
+            description: 'Format of dates (without times) - see PHP-function <a href="https://php.net/date" target="_blank" rel="noreferrer">date()</a>'
         hhmm:
             type: text
-            description: 'Format of Hours-Minutes - see PHP-function <a href="https://php.net/date" target="_blank" rel="noreferrer">date()</a>'
+            description: 'Format of times (without dates) - see PHP-function <a href="https://php.net/date" target="_blank" rel="noreferrer">date()</a>'
         defaultScheme:
             type: text
             allowedValues:
diff --git a/typo3/sysext/core/Documentation/Changelog/12.4.x/Important-103496-ISOFormatUsedForDateRendering.rst b/typo3/sysext/core/Documentation/Changelog/12.4.x/Important-103496-ISOFormatUsedForDateRendering.rst
new file mode 100644
index 000000000000..e648f4e86ba9
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/12.4.x/Important-103496-ISOFormatUsedForDateRendering.rst
@@ -0,0 +1,25 @@
+.. include:: /Includes.rst.txt
+
+.. _important-103496-1711623416:
+
+=======================================================
+Important: #103496 - ISO format used for date rendering
+=======================================================
+
+See :issue:`103496`
+
+Description
+===========
+
+The default format for date rendering configured in :php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy']` has changed.
+
+The former arbitrary :php:`'d-m-y'` format was replaced with the standard ISO 8601 :php:`'Y-m-d'` format.
+
+Examples of dates where the :php:`'d-m-y'` format led to unclear dates:
+
+* A 2-digit year could also be a day in a month: `21-04-23` could be understood as `2021-04-23` instead of `2023-04-21`.
+* The century of years could not be distinguished: `21-04-71` could be `2071-04-21` or `1971-04-21`
+
+This affects date display in various locations so code relying on the previous format (e.g. acceptance tests) must be updated accordingly.
+
+.. index:: Backend, CLI, Frontend, TCA, ext:core
diff --git a/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/RecoveryCodesProviderTest.php b/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/RecoveryCodesProviderTest.php
index 0eb01f1ff5bc..9be276118cdc 100644
--- a/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/RecoveryCodesProviderTest.php
+++ b/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/RecoveryCodesProviderTest.php
@@ -233,8 +233,8 @@ final class RecoveryCodesProviderTest extends FunctionalTestCase
 
         self::assertMatchesRegularExpression('/<td>.*Name.*<td>.*some name/s', $response);
         self::assertMatchesRegularExpression('/<td>.*Recovery codes left.*<td>.*2/s', $response);
-        self::assertMatchesRegularExpression('/<td>.*Last updated.*<td>.*18-03-21/s', $response);
-        self::assertMatchesRegularExpression('/<td>.*Last used.*<td>.*18-03-21/s', $response);
+        self::assertMatchesRegularExpression('/<td>.*Last updated.*<td>.*2021-03-18/s', $response);
+        self::assertMatchesRegularExpression('/<td>.*Last used.*<td>.*2021-03-18/s', $response);
         self::assertMatchesRegularExpression('/<input.*id="regenerateCodes"/s', $response);
     }
 
diff --git a/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/TotpProviderTest.php b/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/TotpProviderTest.php
index 4f7c27ced8dd..f2919ab55257 100644
--- a/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/TotpProviderTest.php
+++ b/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/TotpProviderTest.php
@@ -244,8 +244,8 @@ final class TotpProviderTest extends FunctionalTestCase
         $response = $this->subject->handleRequest($request, $propertyManager, MfaViewType::EDIT)->getBody()->getContents();
 
         self::assertMatchesRegularExpression('/<td>.*Name.*<td>.*some name/s', $response);
-        self::assertMatchesRegularExpression('/<td>.*Last updated.*<td>.*18-03-21/s', $response);
-        self::assertMatchesRegularExpression('/<td>.*Last used.*<td>.*18-03-21/s', $response);
+        self::assertMatchesRegularExpression('/<td>.*Last updated.*<td>.*2021-03-18/s', $response);
+        self::assertMatchesRegularExpression('/<td>.*Last used.*<td>.*2021-03-18/s', $response);
     }
 
     #[Test]
-- 
GitLab