Skip to content

Commit

Permalink
added filters |localDate
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed May 26, 2024
1 parent 900359b commit 577f8ad
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 0 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"ext-iconv": "to use filters |reverse, |substring",
"ext-mbstring": "to use filters like lower, upper, capitalize, ...",
"ext-fileinfo": "to use filter |datastream",
"ext-intl": "to use filter |localDate",
"nette/utils": "to use filter |webalize",
"nette/php-generator": "to use tag {templatePrint}"
},
Expand Down
1 change: 1 addition & 0 deletions src/Latte/Essential/CoreExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ public function getFilters(): array
'join' => [$this->filters, 'implode'],
'last' => [$this->filters, 'last'],
'length' => [$this->filters, 'length'],
'localDate' => [$this->filters, 'localDate'],
'lower' => extension_loaded('mbstring')
? [$this->filters, 'lower']
: fn() => throw new RuntimeException('Filter |lower requires mbstring extension.'),
Expand Down
31 changes: 31 additions & 0 deletions src/Latte/Essential/Filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,37 @@ public function number(
}


/**
* Local date formatting.
* https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax
*/
public function localDate(string|int|\DateTimeInterface|null $time, string $df = 'medium'): ?string
{
if (!preg_match('#^(short|medium|long|full|)\+?(time(\+sec)?)?$#', $df, $m)) {
throw new \InvalidArgumentException("Unknown date format '$df'.");
} elseif ($time == null) { // intentionally ==
return null;
} elseif (is_numeric($time)) {
$time = (new \DateTime)->setTimestamp((int) $time);
} elseif (is_string($time)) {
$time = new \DateTime($time);
}

$df = match ($m[1]) {
'short' => \IntlDateFormatter::SHORT,
'medium' => \IntlDateFormatter::MEDIUM,
'long' => \IntlDateFormatter::LONG,
'full' => \IntlDateFormatter::FULL,
'' => \IntlDateFormatter::NONE,
};
$tf = isset($m[2]) ? (isset($m[3]) ? \IntlDateFormatter::MEDIUM : \IntlDateFormatter::SHORT) : \IntlDateFormatter::NONE;
$formatter = new \IntlDateFormatter($this->getLocale('localDate'), $df, $tf);
$res = $formatter->format($time);
$res = preg_replace('~(\d\.) ~', "\$1\u{a0}", $res);
return $res;
}


private function getLocale(string $name): string
{
if ($this->locale === null) {
Expand Down
50 changes: 50 additions & 0 deletions tests/filters/localDate.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

/**
* Test: Latte\Essential\Filters::localDate()
*/

declare(strict_types=1);

use Latte\Essential\Filters;
use Tester\Assert;

require __DIR__ . '/../bootstrap.php';


test('no locale', function () {
$filters = new Filters;

$filters->localDate(0);
});


test('types of value', function () {
$filters = new Filters;
$filters->locale = 'cs_CZ';

Assert::null($filters->localDate(null));
Assert::same("23.\u{a0}1.\u{a0}1978", $filters->localDate(254_400_000));
Assert::same("5.\u{a0}5.\u{a0}1978", $filters->localDate('1978-05-05'));
Assert::same("5.\u{a0}5.\u{a0}1978", $filters->localDate(new DateTime('1978-05-05')));
});


test('date/time formats', function () {
$filters = new Filters;
$filters->locale = 'cs_CZ';

// date format
Assert::same('05.05.78', $filters->localDate(new DateTime('1978-05-05'), 'short'));
Assert::same("5.\u{a0}5.\u{a0}1978", $filters->localDate(new DateTime('1978-05-05'), 'medium'));
Assert::same("5.\u{a0}května 1978", $filters->localDate(new DateTime('1978-05-05'), 'long'));
Assert::same("pátek 5.\u{a0}května 1978", $filters->localDate(new DateTime('1978-05-05'), 'full'));

// time format
Assert::same('12:13', $filters->localDate(new DateTime('12:13:14'), 'time'));
Assert::same('12:13:14', $filters->localDate(new DateTime('12:13:14'), 'time+sec'));

// combined
Assert::same('05.05.78 12:13', $filters->localDate(new DateTime('1978-05-05 12:13:14'), 'short+time'));
Assert::same('05.05.78 12:13:14', $filters->localDate(new DateTime('1978-05-05 12:13:14'), 'short+time+sec'));
});

0 comments on commit 577f8ad

Please sign in to comment.