Fix Github #1844 - Monthly views previous/next month links during month

end. Avoid deprecated strftime function. Got tests to pass in PHP 8.1.
This commit is contained in:
Keith Carangelo 2022-03-31 15:42:25 -04:00
parent f6076a9275
commit 6ecc4745f4
8 changed files with 106 additions and 49 deletions

View file

@ -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,

View file

@ -60,6 +60,11 @@ public static function extractRequestedDateTime(
;
}
// 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())

View file

@ -30,9 +30,13 @@ function is_iterable($var)
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();

View file

@ -667,11 +667,11 @@ public function testSimpleRssWeekly(): void
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 @@ public function testSimpleRssMonthly(): void
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']);

View file

@ -258,7 +258,7 @@ public function getStartDatesByType(): array
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 @@ public function getEndDatesByType(): array
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')],
];
}

View file

@ -6,13 +6,25 @@
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 @@ public function testDateFormat()
*/
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 @@ public function testAutoLocaleValid()
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 @@ public function testAutoLocaleMultipleFirstValid()
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 @@ public function testAutoLocaleBlank()
{
$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 @@ public function testAutoLocaleBlank()
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);
}

View file

@ -6,13 +6,25 @@
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 @@ public function testDateFormat()
*/
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 @@ public function testAutoLocaleMultipleFirstValid()
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 @@ public function testAutoLocaleBlank()
{
$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 @@ public function testAutoLocaleBlank()
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);
}

View file

@ -6,13 +6,25 @@
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 @@ public function testDateFormat()
*/
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 @@ public function testAutoLocaleMultipleFirstValid()
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 @@ public function testAutoLocaleBlank()
{
$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 @@ public function testAutoLocaleBlank()
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);
}