diff --git a/.gitignore b/.gitignore index 5b647aa1..de11480f 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ coverage sandbox phpmd.html phpdoc.xml +.phpunit.result.cache # User plugin configuration plugins/* diff --git a/application/Utils.php b/application/Utils.php index c5cd884b..073004cf 100644 --- a/application/Utils.php +++ b/application/Utils.php @@ -197,7 +197,7 @@ function generateLocation($referer, $host, $loopTerms = []) function autoLocale($headerLocale) { // Default if browser does not send HTTP_ACCEPT_LANGUAGE - $locales = ['en_US', 'en_US.utf8', 'en_US.UTF-8']; + $locales = ['en_US.UTF-8', 'en_US.utf8', 'en_US']; if (! empty($headerLocale)) { if (preg_match_all('/([a-z]{2,3})[-_]?([a-z]{2})?,?/i', $headerLocale, $matches, PREG_SET_ORDER)) { $attempts = []; @@ -314,10 +314,12 @@ function format_date($date, $time = true, $intl = true) } if (! $intl || ! class_exists('IntlDateFormatter')) { - $format = $time ? '%c' : '%x'; - return strftime($format, $date->getTimestamp()); + $format = 'F j, Y'; + if ($time) { + $format .= ' h:i:s A \G\M\TP'; + } + return $date->format($format); } - $formatter = new IntlDateFormatter( setlocale(LC_TIME, 0), IntlDateFormatter::LONG, diff --git a/application/helper/DailyPageHelper.php b/application/helper/DailyPageHelper.php index 05f95812..cb4494a8 100644 --- a/application/helper/DailyPageHelper.php +++ b/application/helper/DailyPageHelper.php @@ -60,6 +60,11 @@ class DailyPageHelper ; } + // Don't use today's day of month (github issue #1844) + if ($type === static::MONTH) { + $format = '!' . $format; + } + // W is not supported by createFromFormat... if ($type === static::WEEK) { return (new DateTimeImmutable()) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 9d05b3d5..e0403296 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -30,9 +30,13 @@ require_once 'tests/TestCase.php'; require_once 'tests/container/ShaarliTestContainer.php'; require_once 'tests/front/controller/visitor/FrontControllerMockHelper.php'; require_once 'tests/front/controller/admin/FrontAdminControllerMockHelper.php'; +require_once 'tests/updater/DummyUpdater.php'; +require_once 'tests/utils/FakeApplicationUtils.php'; +require_once 'tests/utils/FakeBookmarkService.php'; require_once 'tests/utils/FakeConfigManager.php'; require_once 'tests/utils/ReferenceHistory.php'; require_once 'tests/utils/ReferenceLinkDB.php'; +require_once 'tests/utils/ReferenceSessionIdHashes.php'; ReferenceSessionIdHashes::genAllHashes(); diff --git a/tests/front/controller/visitor/DailyControllerTest.php b/tests/front/controller/visitor/DailyControllerTest.php index b6574b6c..a0dd54e1 100644 --- a/tests/front/controller/visitor/DailyControllerTest.php +++ b/tests/front/controller/visitor/DailyControllerTest.php @@ -667,11 +667,11 @@ class DailyControllerTest extends TestCase public function testSimpleRssMonthly(): void { $dates = [ - new \DateTimeImmutable('2020-05-19'), + new \DateTimeImmutable('2022-02-19'), new \DateTimeImmutable('2020-04-13'), ]; $expectedDates = [ - new \DateTimeImmutable('2020-05-31 23:59:59'), + new \DateTimeImmutable('2022-02-28 23:59:59'), new \DateTimeImmutable('2020-04-30 23:59:59'), ]; @@ -710,7 +710,7 @@ class DailyControllerTest extends TestCase static::assertEquals($date, $day['date']); static::assertSame($date->format(\DateTime::RSS), $day['date_rss']); - static::assertSame('May, 2020', $day['date_human']); + static::assertSame('February, 2022', $day['date_human']); static::assertSame('http://shaarli/subfolder/daily?month=' . $dates[0]->format('Ym'), $day['absolute_url']); static::assertCount(1, $day['links']); diff --git a/tests/helper/DailyPageHelperTest.php b/tests/helper/DailyPageHelperTest.php index 4a4b95b2..8dab908d 100644 --- a/tests/helper/DailyPageHelperTest.php +++ b/tests/helper/DailyPageHelperTest.php @@ -258,7 +258,7 @@ class DailyPageHelperTest extends TestCase return [ [DailyPageHelper::DAY, new DateTimeImmutable('2020-10-09 04:05:06'), new DateTime('2020-10-09 00:00:00')], [DailyPageHelper::WEEK, new DateTimeImmutable('2020-10-09 04:05:06'), new DateTime('2020-10-05 00:00:00')], - [DailyPageHelper::MONTH, new DateTimeImmutable('2020-10-09 04:05:06'), new DateTime('2020-10-01 00:00:00')], + [DailyPageHelper::MONTH, new DateTimeImmutable('2022-03-30 04:05:06'), new DateTime('2022-03-01 00:00:00')], ]; } @@ -270,7 +270,8 @@ class DailyPageHelperTest extends TestCase return [ [DailyPageHelper::DAY, new DateTimeImmutable('2020-10-09 04:05:06'), new DateTime('2020-10-09 23:59:59')], [DailyPageHelper::WEEK, new DateTimeImmutable('2020-10-09 04:05:06'), new DateTime('2020-10-11 23:59:59')], - [DailyPageHelper::MONTH, new DateTimeImmutable('2020-10-09 04:05:06'), new DateTime('2020-10-31 23:59:59')], + [DailyPageHelper::MONTH, new DateTimeImmutable('2022-02-28 04:05:06'), new DateTime('2022-02-28 23:59:59')], + [DailyPageHelper::MONTH, new DateTimeImmutable('2022-03-30 04:05:06'), new DateTime('2022-03-31 23:59:59')], ]; } diff --git a/tests/languages/de/UtilsDeTest.php b/tests/languages/de/UtilsDeTest.php index 9713009d..d7a16eac 100644 --- a/tests/languages/de/UtilsDeTest.php +++ b/tests/languages/de/UtilsDeTest.php @@ -6,13 +6,25 @@ use DateTime; class UtilsDeTest extends UtilsTest { + /** + * Test for international date formatter class. Other tests + * will fail without it! + */ + public function testIntlDateFormatter() + { + $this->assertTrue(class_exists('IntlDateFormatter')); + } + /** * Test date_format(). */ public function testDateFormat() { - $date = DateTime::createFromFormat('Ymd_His', '20170101_101112'); - $this->assertRegExp('/1\. Januar 2017 (um )?10:11:12 GMT\+0?3(:00)?/', format_date($date, true, true)); + $current = setlocale(LC_ALL, 0); + autoLocale('de-de'); + $date = DateTime::createFromFormat('Ymd_His', '20170102_201112'); + $this->assertRegExp('/2\. Januar 2017 (um )?20:11:12 GMT\+0?3(:00)?/', format_date($date, true, true)); + setlocale(LC_ALL, $current); } /** @@ -20,26 +32,29 @@ class UtilsDeTest extends UtilsTest */ public function testDateFormatNoTime() { - $date = DateTime::createFromFormat('Ymd_His', '20170101_101112'); - $this->assertRegExp('/1\. Januar 2017/', format_date($date, false, true)); + $current = setlocale(LC_ALL, 0); + autoLocale('de-de'); + $date = DateTime::createFromFormat('Ymd_His', '20170102_201112'); + $this->assertRegExp('/2\. Januar 2017/', format_date($date, false, true)); + setlocale(LC_ALL, $current); } /** - * Test date_format() using builtin PHP function strftime. + * Test date_format() using DateTime */ public function testDateFormatDefault() { - $date = DateTime::createFromFormat('Ymd_His', '20170101_101112'); - $this->assertEquals('So 01 Jan 2017 10:11:12 EAT', format_date($date, true, false)); + $date = DateTime::createFromFormat('Ymd_His', '20170102_101112'); + $this->assertEquals('January 2, 2017 10:11:12 AM GMT+03:00', format_date($date, true, false)); } /** - * Test date_format() using builtin PHP function strftime without time. + * Test date_format() using DateTime */ public function testDateFormatDefaultNoTime() { $date = DateTime::createFromFormat('Ymd_His', '20170201_101112'); - $this->assertEquals('01.02.2017', format_date($date, false, false)); + $this->assertEquals('February 1, 2017', format_date($date, false, false)); } /** @@ -61,7 +76,7 @@ class UtilsDeTest extends UtilsTest public function testAutoLocaleValidAlternative() { $current = setlocale(LC_ALL, 0); - $header = 'en_us.UTF8'; + $header = 'en_US.UTF-8'; autoLocale($header); $this->assertEquals('en_US.utf8', setlocale(LC_ALL, 0)); @@ -87,7 +102,7 @@ class UtilsDeTest extends UtilsTest public function testAutoLocaleMultipleSecondAvailable() { $current = setlocale(LC_ALL, 0); - $header = 'mag_IN,fr-fr'; + $header = 'mgg_IN,fr-fr'; autoLocale($header); $this->assertEquals('fr_FR.utf8', setlocale(LC_ALL, 0)); @@ -101,7 +116,7 @@ class UtilsDeTest extends UtilsTest { $current = setlocale(LC_ALL, 0); autoLocale(''); - $this->assertEquals('en_US.utf8', setlocale(LC_ALL, 0)); + $this->assertEquals('en_US.UTF-8', setlocale(LC_ALL, 0)); setlocale(LC_ALL, $current); } @@ -112,8 +127,8 @@ class UtilsDeTest extends UtilsTest public function testAutoLocaleUnavailable() { $current = setlocale(LC_ALL, 0); - autoLocale('mag_IN'); - $this->assertEquals('en_US.utf8', setlocale(LC_ALL, 0)); + autoLocale('mgg_IN'); + $this->assertEquals('en_US.UTF-8', setlocale(LC_ALL, 0)); setlocale(LC_ALL, $current); } diff --git a/tests/languages/en/UtilsEnTest.php b/tests/languages/en/UtilsEnTest.php index 1e297b67..f1e21b9a 100644 --- a/tests/languages/en/UtilsEnTest.php +++ b/tests/languages/en/UtilsEnTest.php @@ -6,13 +6,25 @@ use DateTime; class UtilsEnTest extends UtilsTest { + /** + * Test for international date formatter class. Other tests + * will fail without it! + */ + public function testIntlDateFormatter() + { + $this->assertTrue(class_exists('IntlDateFormatter')); + } + /** * Test date_format(). */ public function testDateFormat() { - $date = DateTime::createFromFormat('Ymd_His', '20170101_101112'); - $this->assertRegExp('/January 1, 2017 (at )?10:11:12 AM GMT\+0?3(:00)?/', format_date($date, true, true)); + $current = setlocale(LC_ALL, 0); + autoLocale('en_US.UTF-8'); + $date = DateTime::createFromFormat('Ymd_His', '20170102_201112'); + $this->assertRegExp('/January 2, 2017 (at )?8:11:12 PM GMT\+0?3(:00)?/', format_date($date, true, true)); + setlocale(LC_ALL, $current); } /** @@ -20,26 +32,29 @@ class UtilsEnTest extends UtilsTest */ public function testDateFormatNoTime() { - $date = DateTime::createFromFormat('Ymd_His', '20170101_101112'); - $this->assertRegExp('/January 1, 2017/', format_date($date, false, true)); + $current = setlocale(LC_ALL, 0); + autoLocale('en_US.UTF-8'); + $date = DateTime::createFromFormat('Ymd_His', '20170102_201112'); + $this->assertRegExp('/January 2, 2017/', format_date($date, false, true)); + setlocale(LC_ALL, $current); } /** - * Test date_format() using builtin PHP function strftime. + * Test date_format() using DateTime */ public function testDateFormatDefault() { - $date = DateTime::createFromFormat('Ymd_His', '20170101_101112'); - $this->assertEquals('Sun 01 Jan 2017 10:11:12 AM EAT', format_date($date, true, false)); + $date = DateTime::createFromFormat('Ymd_His', '20170102_101112'); + $this->assertEquals('January 2, 2017 10:11:12 AM GMT+03:00', format_date($date, true, false)); } /** - * Test date_format() using builtin PHP function strftime without time. + * Test date_format() using DateTime */ public function testDateFormatDefaultNoTime() { $date = DateTime::createFromFormat('Ymd_His', '20170201_101112'); - $this->assertEquals('02/01/2017', format_date($date, false, false)); + $this->assertEquals('February 1, 2017', format_date($date, false, false)); } /** @@ -87,7 +102,7 @@ class UtilsEnTest extends UtilsTest public function testAutoLocaleMultipleSecondAvailable() { $current = setlocale(LC_ALL, 0); - $header = 'mag_IN,fr-fr'; + $header = 'mgg_IN,fr-fr'; autoLocale($header); $this->assertEquals('fr_FR.utf8', setlocale(LC_ALL, 0)); @@ -101,7 +116,7 @@ class UtilsEnTest extends UtilsTest { $current = setlocale(LC_ALL, 0); autoLocale(''); - $this->assertEquals('en_US.utf8', setlocale(LC_ALL, 0)); + $this->assertEquals('en_US.UTF-8', setlocale(LC_ALL, 0)); setlocale(LC_ALL, $current); } @@ -112,8 +127,8 @@ class UtilsEnTest extends UtilsTest public function testAutoLocaleUnavailable() { $current = setlocale(LC_ALL, 0); - autoLocale('mag_IN'); - $this->assertEquals('en_US.utf8', setlocale(LC_ALL, 0)); + autoLocale('mgg_IN'); + $this->assertEquals('en_US.UTF-8', setlocale(LC_ALL, 0)); setlocale(LC_ALL, $current); } diff --git a/tests/languages/fr/UtilsFrTest.php b/tests/languages/fr/UtilsFrTest.php index 3a26250e..799fa5c9 100644 --- a/tests/languages/fr/UtilsFrTest.php +++ b/tests/languages/fr/UtilsFrTest.php @@ -6,13 +6,25 @@ use DateTime; class UtilsFrTest extends UtilsTest { + /** + * Test for international date formatter class. Other tests + * will fail without it! + */ + public function testIntlDateFormatter() + { + $this->assertTrue(class_exists('IntlDateFormatter')); + } + /** * Test date_format(). */ public function testDateFormat() { - $date = DateTime::createFromFormat('Ymd_His', '20170101_101112'); - $this->assertRegExp('/1 janvier 2017 (à )?10:11:12 UTC\+0?3(:00)?/', format_date($date)); + $current = setlocale(LC_ALL, 0); + autoLocale('fr-fr'); + $date = DateTime::createFromFormat('Ymd_His', '20170102_201112'); + $this->assertRegExp('/2 janvier 2017 (à )?20:11:12 UTC\+0?3(:00)?/', format_date($date)); + setlocale(LC_ALL, $current); } /** @@ -20,26 +32,29 @@ class UtilsFrTest extends UtilsTest */ public function testDateFormatNoTime() { - $date = DateTime::createFromFormat('Ymd_His', '20170101_101112'); - $this->assertRegExp('/1 janvier 2017/', format_date($date, false, true)); + $current = setlocale(LC_ALL, 0); + autoLocale('fr-fr'); + $date = DateTime::createFromFormat('Ymd_His', '20170102_201112'); + $this->assertRegExp('/2 janvier 2017/', format_date($date, false, true)); + setlocale(LC_ALL, $current); } /** - * Test date_format() using builtin PHP function strftime. + * Test date_format() using DateTime */ public function testDateFormatDefault() { - $date = DateTime::createFromFormat('Ymd_His', '20170101_101112'); - $this->assertEquals('dim. 01 janv. 2017 10:11:12 EAT', format_date($date, true, false)); + $date = DateTime::createFromFormat('Ymd_His', '20170102_101112'); + $this->assertEquals('January 2, 2017 10:11:12 AM GMT+03:00', format_date($date, true, false)); } /** - * Test date_format() using builtin PHP function strftime without time. + * Test date_format() using DateTime */ public function testDateFormatDefaultNoTime() { $date = DateTime::createFromFormat('Ymd_His', '20170201_101112'); - $this->assertEquals('01/02/2017', format_date($date, false, false)); + $this->assertEquals('February 1, 2017', format_date($date, false, false)); } /** @@ -87,7 +102,7 @@ class UtilsFrTest extends UtilsTest public function testAutoLocaleMultipleSecondAvailable() { $current = setlocale(LC_ALL, 0); - $header = 'mag_IN,de-de'; + $header = 'mgg_IN,de-de'; autoLocale($header); $this->assertEquals('de_DE.utf8', setlocale(LC_ALL, 0)); @@ -101,7 +116,7 @@ class UtilsFrTest extends UtilsTest { $current = setlocale(LC_ALL, 0); autoLocale(''); - $this->assertEquals('en_US.utf8', setlocale(LC_ALL, 0)); + $this->assertEquals('en_US.UTF-8', setlocale(LC_ALL, 0)); setlocale(LC_ALL, $current); } @@ -112,8 +127,8 @@ class UtilsFrTest extends UtilsTest public function testAutoLocaleUnavailable() { $current = setlocale(LC_ALL, 0); - autoLocale('mag_IN'); - $this->assertEquals('en_US.utf8', setlocale(LC_ALL, 0)); + autoLocale('mgg_IN'); + $this->assertEquals('en_US.UTF-8', setlocale(LC_ALL, 0)); setlocale(LC_ALL, $current); }