From 6f159e69bea42f1c018c21821cebe67520ad2afc Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 12 Mar 2025 22:46:36 -0400 Subject: [PATCH 1/2] Add support for more datetime formats - Unix Timestamp - RFC 3339 extended + timezone name in square brackets - Address https://github.com/friendica/friendica/issues/14647#issuecomment-2719430131 --- src/Util/DateTimeFormat.php | 6 +- tests/src/Util/DateTimeFormatTest.php | 81 +++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/src/Util/DateTimeFormat.php b/src/Util/DateTimeFormat.php index 42b49cbf7d..830b50a2fe 100644 --- a/src/Util/DateTimeFormat.php +++ b/src/Util/DateTimeFormat.php @@ -117,7 +117,7 @@ class DateTimeFormat $tz_to = 'UTC'; } - if (($s === '') || (!is_string($s))) { + if ($s === '') { $s = 'now'; } @@ -135,7 +135,8 @@ class DateTimeFormat } try { - $d = new DateTime($s, $from_obj); + $d = DateTime::createFromFormat('U', $s, $from_obj) + ?: new DateTime($s, $from_obj); } catch (Exception $e) { try { $d = new DateTime(self::fix($s), $from_obj); @@ -176,6 +177,7 @@ class DateTimeFormat $pregPatterns = [ ['#(\w+), (\d+ \w+ \d+) (\d+:\d+:\d+) (.+)#', '$2 $3 $4'], ['#(\d+:\d+) (\w+), (\w+) (\d+), (\d+)#', '$1 $2 $3 $4 $5'], + ['#\[[^\]]*\]#', ''], // 2025-03-07T08:54:14.341+01:00[Europe/Berlin] ]; foreach ($pregPatterns as $pattern) { diff --git a/tests/src/Util/DateTimeFormatTest.php b/tests/src/Util/DateTimeFormatTest.php index 9137659ba8..186741a67c 100644 --- a/tests/src/Util/DateTimeFormatTest.php +++ b/tests/src/Util/DateTimeFormatTest.php @@ -125,6 +125,10 @@ class DateTimeFormatTest extends MockedTestCase 'expectedDate' => '2023-04-02T17:22:42+05:30', 'dateString' => '2023-04-02\T17:22:42+05:30' ], + '2025-03-07T08:54:14.341+01:00[Europe/Berlin]' => [ + 'expectedDate' => '2025-03-07T08:54:14+01:00', + 'dateString' => '2025-03-07T08:54:14.341+01:00[Europe/Berlin]' + ], ]; } @@ -156,4 +160,81 @@ class DateTimeFormatTest extends MockedTestCase $this->assertEquals(259200, $now - $date); } + + public function dataConvert() { + return [ + 'unix timestamp' => [ + 'expected' => '2025-03-12 16:18:27', + 's' => '1741796307', + ], + 'ATOM' => [ + 'expected' => '2022-06-02 15:58:35', + 's' => '2022-06-02T16:58:35+01:00', + ], + 'COOKIE' => [ + 'expected' => '2022-06-02 14:58:35', + 's' => 'Thursday, 02-Jun-2022 16:58:35 Africa/Cairo', + ], + 'ISO 8601/RFC 3339' => [ + 'expected' => '2022-06-02 13:58:35', + 's' => '2022-06-02T16:58:35+0300', + ], + 'RFC 822/RFC 1036' => [ + 'expected' => '2022-06-02 12:58:35', + 's' => 'Thu, 02 Jun 22 16:58:35 +0400', + ], + 'RFC 850' => [ + 'expected' => '2022-06-02 11:58:35', + 's' => 'Thursday, 02-Jun-22 16:58:35 Indian/Kerguelen', + ], + 'RFC 1123/RFC 2822/RSS' => [ + 'expected' => '2022-06-02 10:58:35', + 's' => 'Thu, 02 Jun 2022 16:58:35 +0600', + ], + 'RFC 3339/W3C' => [ + 'expected' => '2025-03-07 01:54:14', + 's' => '2025-03-07T08:54:14+07:00', + ], + 'RFC 3339 extended' => [ + 'expected' => '2025-03-07 00:54:14', + 's' => '2025-03-07T08:54:14.341+08:00', + ], + 'RFC 7231' => [ + 'expected' => '2022-06-02 07:58:35', + 's' => 'Thu, 02 Jun 2022 16:58:35 Asia/Tokyo', + ], + ]; + } + + /** + * @dataProvider dataConvert + */ + public function testConvert($expected, string $s = 'now', string $tz_to = 'UTC', string $tz_from = 'UTC', string $format = DateTimeFormat::MYSQL) + { + $this->assertSame($expected, DateTimeFormat::convert($s, $tz_to, $tz_from, $format)); + } + + public function dataConvertNow() + { + return [ + 'now missing' => [ + ], + 'now empty' => [ + 's' => '', + ], + 'now now' => [ + 's' => 'now', + ], + ]; + } + + /** + * @dataProvider dataConvertNow + */ + public function testConvertNow(string $s = 'now', string $tz_to = 'UTC', string $tz_from = 'UTC', string $format = DateTimeFormat::MYSQL) + { + $this->assertSame(date(DateTimeFormat::MYSQL), DateTimeFormat::convert($s, $tz_to, $tz_from, $format)); + } + + } From 47e4bad15199f744150365f25db644e4c4795b24 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Tue, 18 Mar 2025 19:07:25 -0400 Subject: [PATCH 2/2] Fix formatting in DateTimeFormatTest --- tests/src/Util/DateTimeFormatTest.php | 69 ++++++++++++++------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/tests/src/Util/DateTimeFormatTest.php b/tests/src/Util/DateTimeFormatTest.php index 186741a67c..6cc506807e 100644 --- a/tests/src/Util/DateTimeFormatTest.php +++ b/tests/src/Util/DateTimeFormatTest.php @@ -16,39 +16,39 @@ class DateTimeFormatTest extends MockedTestCase { return [ 'validNormal' => [ - 'input' => '1990-10', + 'input' => '1990-10', 'assert' => true, ], 'validOneCharMonth' => [ - 'input' => '1990-1', + 'input' => '1990-1', 'assert' => true, ], 'validTwoCharMonth' => [ - 'input' => '1990-01', + 'input' => '1990-01', 'assert' => true, ], 'invalidFormat' => [ - 'input' => '199-11', + 'input' => '199-11', 'assert' => false, ], 'invalidFormat2' => [ - 'input' => '1990-15', + 'input' => '1990-15', 'assert' => false, ], 'invalidFormat3' => [ - 'input' => '99-101', + 'input' => '99-101', 'assert' => false, ], 'invalidFormat4' => [ - 'input' => '11-1990', + 'input' => '11-1990', 'assert' => false, ], 'invalidFuture' => [ - 'input' => '3030-12', + 'input' => '3030-12', 'assert' => false, ], 'invalidYear' => [ - 'input' => '-100-10', + 'input' => '-100-10', 'assert' => false, ], ]; @@ -79,55 +79,55 @@ class DateTimeFormatTest extends MockedTestCase return [ 'Mo, 19 Sep 2022 14:51:00 +0200' => [ 'expectedDate' => '2022-09-19T14:51:00+02:00', - 'dateString' => 'Mo, 19 Sep 2022 14:51:00 +0200', + 'dateString' => 'Mo, 19 Sep 2022 14:51:00 +0200', ], '2020-11-21T12:00:13.745339ZZ' => [ 'expectedDate' => '2020-11-21T12:00:13+00:00', - 'dateString' => '2020-11-21T12:00:13.745339ZZ', + 'dateString' => '2020-11-21T12:00:13.745339ZZ', ], '2016-09-09T13:32:00ZZ' => [ 'expectedDate' => '2016-09-09T13:32:00+00:00', - 'dateString' => '2016-09-09T13:32:00ZZ', + 'dateString' => '2016-09-09T13:32:00ZZ', ], 'Sun, 10/03/2021 - 12:41' => [ 'expectedDate' => '2021-10-03T12:41:00+00:00', - 'dateString' => 'Sun, 10/03/2021 - 12:41', + 'dateString' => 'Sun, 10/03/2021 - 12:41', ], '4:30 PM, Sep 13, 2022' => [ 'expectedDate' => '2022-09-13T16:30:00+00:00', - 'dateString' => '4:30 PM, Sep 13, 2022', + 'dateString' => '4:30 PM, Sep 13, 2022', ], 'August 27, 2022 - 21:00' => [ 'expectedDate' => '2022-08-27T21:00:00+00:00', - 'dateString' => 'August 27, 2022 - 21:00', + 'dateString' => 'August 27, 2022 - 21:00', ], '2021-09-19T14:06:03+00:00' => [ 'expectedDate' => '2021-09-19T14:06:03+00:00', - 'dateString' => '2021-09-19T14:06:03+00:00', + 'dateString' => '2021-09-19T14:06:03+00:00', ], 'Eastern Time timezone' => [ 'expectedDate' => '2022-09-30T00:00:00-05:00', - 'dateString' => 'September 30, 2022, 12:00 a.m. ET', + 'dateString' => 'September 30, 2022, 12:00 a.m. ET', ], 'German date time string' => [ 'expectedDate' => '2022-10-05T16:34:00+02:00', - 'dateString' => '05 Okt 2022 16:34:00 +0200', + 'dateString' => '05 Okt 2022 16:34:00 +0200', ], '(Coordinated Universal Time)' => [ 'expectedDate' => '2022-12-30T14:29:10+00:00', - 'dateString' => 'Fri Dec 30 2022 14:29:10 GMT+0000 (Coordinated Universal Time)', + 'dateString' => 'Fri Dec 30 2022 14:29:10 GMT+0000 (Coordinated Universal Time)', ], 'Double HTML encode' => [ 'expectedDate' => '2015-05-22T08:48:00+12:00', - 'dateString' => '2015-05-22T08:48:00+12:00' + 'dateString' => '2015-05-22T08:48:00+12:00' ], '2023-04-02\T17:22:42+05:30' => [ 'expectedDate' => '2023-04-02T17:22:42+05:30', - 'dateString' => '2023-04-02\T17:22:42+05:30' + 'dateString' => '2023-04-02\T17:22:42+05:30' ], '2025-03-07T08:54:14.341+01:00[Europe/Berlin]' => [ 'expectedDate' => '2025-03-07T08:54:14+01:00', - 'dateString' => '2025-03-07T08:54:14.341+01:00[Europe/Berlin]' + 'dateString' => '2025-03-07T08:54:14.341+01:00[Europe/Berlin]' ], ]; } @@ -155,53 +155,54 @@ class DateTimeFormatTest extends MockedTestCase */ public function testConvertRelative() { - $now = DateTimeFormat::utcNow('U'); + $now = DateTimeFormat::utcNow('U'); $date = DateTimeFormat::utc('now - 3 days', 'U'); $this->assertEquals(259200, $now - $date); } - public function dataConvert() { + public function dataConvert() + { return [ 'unix timestamp' => [ 'expected' => '2025-03-12 16:18:27', - 's' => '1741796307', + 's' => '1741796307', ], 'ATOM' => [ 'expected' => '2022-06-02 15:58:35', - 's' => '2022-06-02T16:58:35+01:00', + 's' => '2022-06-02T16:58:35+01:00', ], 'COOKIE' => [ 'expected' => '2022-06-02 14:58:35', - 's' => 'Thursday, 02-Jun-2022 16:58:35 Africa/Cairo', + 's' => 'Thursday, 02-Jun-2022 16:58:35 Africa/Cairo', ], 'ISO 8601/RFC 3339' => [ 'expected' => '2022-06-02 13:58:35', - 's' => '2022-06-02T16:58:35+0300', + 's' => '2022-06-02T16:58:35+0300', ], 'RFC 822/RFC 1036' => [ 'expected' => '2022-06-02 12:58:35', - 's' => 'Thu, 02 Jun 22 16:58:35 +0400', + 's' => 'Thu, 02 Jun 22 16:58:35 +0400', ], 'RFC 850' => [ 'expected' => '2022-06-02 11:58:35', - 's' => 'Thursday, 02-Jun-22 16:58:35 Indian/Kerguelen', + 's' => 'Thursday, 02-Jun-22 16:58:35 Indian/Kerguelen', ], 'RFC 1123/RFC 2822/RSS' => [ 'expected' => '2022-06-02 10:58:35', - 's' => 'Thu, 02 Jun 2022 16:58:35 +0600', + 's' => 'Thu, 02 Jun 2022 16:58:35 +0600', ], 'RFC 3339/W3C' => [ 'expected' => '2025-03-07 01:54:14', - 's' => '2025-03-07T08:54:14+07:00', + 's' => '2025-03-07T08:54:14+07:00', ], 'RFC 3339 extended' => [ 'expected' => '2025-03-07 00:54:14', - 's' => '2025-03-07T08:54:14.341+08:00', + 's' => '2025-03-07T08:54:14.341+08:00', ], 'RFC 7231' => [ 'expected' => '2022-06-02 07:58:35', - 's' => 'Thu, 02 Jun 2022 16:58:35 Asia/Tokyo', + 's' => 'Thu, 02 Jun 2022 16:58:35 Asia/Tokyo', ], ]; }