Skip to content

Commit 761208f

Browse files
committed
$language arg for DateTimeHelper::humanDuration()
Resolves #16332
1 parent 1d89a66 commit 761208f

3 files changed

Lines changed: 41 additions & 12 deletions

File tree

CHANGELOG-WIP.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
## Administration
77
- The Queue Manager utility now shows jobs’ class names. ([#16228](https://github.com/craftcms/cms/pull/16228))
88

9+
## Development
10+
- The `|duration` Twig filter now has a `language` argument. ([#16332](https://github.com/craftcms/cms/pull/16332))
11+
12+
## Extensibility
13+
- `craft\helpers\DateTimeHelper::humanDuration()` now has a `$language` argument. ([#16332](https://github.com/craftcms/cms/pull/16332))
14+
915
## System
1016
- Database rows with foreign keys referencing nonexistent rows are now deleted via garbage collection.
1117
- Pages which contain image transform generation URLs now set no-cache headers. ([#16195](https://github.com/craftcms/cms/discussions/16195))

src/helpers/DateTimeHelper.php

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -759,10 +759,11 @@ public static function isValidIntervalString(string $intervalString): bool
759759
*
760760
* @param mixed $dateInterval The value, represented as either a [[\DateInterval]] object, an interval duration string, or a number of seconds.
761761
* @param bool|null $showSeconds Whether the duration string should include the number of seconds
762+
* @param string|null $language The language code that should be used. (Defaults to the current application language.)
762763
* @return string
763764
* @since 4.2.0
764765
*/
765-
public static function humanDuration(mixed $dateInterval, ?bool $showSeconds = null): string
766+
public static function humanDuration(mixed $dateInterval, ?bool $showSeconds = null, ?string $language = null): string
766767
{
767768
$dateInterval = static::toDateInterval($dateInterval) ?: new DateInterval('PT0S');
768769
$secondsOnly = !$dateInterval->y && !$dateInterval->m && !$dateInterval->d && !$dateInterval->h && !$dateInterval->i;
@@ -774,24 +775,34 @@ public static function humanDuration(mixed $dateInterval, ?bool $showSeconds = n
774775
$timeComponents = [];
775776

776777
if ($dateInterval->y) {
777-
$timeComponents[] = Craft::t('app', '{num, number} {num, plural, =1{year} other{years}}', ['num' => $dateInterval->y]);
778+
$timeComponents[] = Craft::t('app', '{num, number} {num, plural, =1{year} other{years}}', [
779+
'num' => $dateInterval->y,
780+
], $language);
778781
}
779782

780783
if ($dateInterval->m) {
781-
$timeComponents[] = Craft::t('app', '{num, number} {num, plural, =1{month} other{months}}', ['num' => $dateInterval->m]);
784+
$timeComponents[] = Craft::t('app', '{num, number} {num, plural, =1{month} other{months}}', [
785+
'num' => $dateInterval->m,
786+
], $language);
782787
}
783788

784789
if ($dateInterval->d) {
785790
// Is it an exact number of weeks?
786791
if ($dateInterval->d % 7 === 0) {
787-
$timeComponents[] = Craft::t('app', '{num, number} {num, plural, =1{week} other{weeks}}', ['num' => $dateInterval->d / 7]);
792+
$timeComponents[] = Craft::t('app', '{num, number} {num, plural, =1{week} other{weeks}}', [
793+
'num' => $dateInterval->d / 7,
794+
], $language);
788795
} else {
789-
$timeComponents[] = Craft::t('app', '{num, number} {num, plural, =1{day} other{days}}', ['num' => $dateInterval->d]);
796+
$timeComponents[] = Craft::t('app', '{num, number} {num, plural, =1{day} other{days}}', [
797+
'num' => $dateInterval->d,
798+
], $language);
790799
}
791800
}
792801

793802
if ($dateInterval->h) {
794-
$timeComponents[] = Craft::t('app', '{num, number} {num, plural, =1{hour} other{hours}}', ['num' => $dateInterval->h]);
803+
$timeComponents[] = Craft::t('app', '{num, number} {num, plural, =1{hour} other{hours}}', [
804+
'num' => $dateInterval->h,
805+
], $language);
795806
}
796807

797808
$minutes = $dateInterval->i;
@@ -806,11 +817,15 @@ public static function humanDuration(mixed $dateInterval, ?bool $showSeconds = n
806817
}
807818

808819
if ($minutes) {
809-
$timeComponents[] = Craft::t('app', '{num, number} {num, plural, =1{minute} other{minutes}}', ['num' => $minutes]);
820+
$timeComponents[] = Craft::t('app', '{num, number} {num, plural, =1{minute} other{minutes}}', [
821+
'num' => $minutes,
822+
], $language);
810823
}
811824

812825
if ($showSeconds && ($dateInterval->s || empty($timeComponents))) {
813-
$timeComponents[] = Craft::t('app', '{num, number} {num, plural, =1{second} other{seconds}}', ['num' => $dateInterval->s]);
826+
$timeComponents[] = Craft::t('app', '{num, number} {num, plural, =1{second} other{seconds}}', [
827+
'num' => $dateInterval->s,
828+
], $language);
814829
}
815830

816831
$last = array_pop($timeComponents);
@@ -819,10 +834,11 @@ public static function humanDuration(mixed $dateInterval, ?bool $showSeconds = n
819834
if (count($timeComponents) > 1) {
820835
$string .= ',';
821836
}
822-
$string .= ' ' . Craft::t('app', 'and') . ' ';
837+
$string .= ' ' . Craft::t('app', 'and', language: $language) . ' ';
823838
} else {
824839
$string = '';
825840
}
841+
826842
$string .= $last;
827843
return $string;
828844
}

tests/unit/helpers/DateTimeHelperTest.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -403,11 +403,16 @@ public function testIsIso8601(bool $expected, mixed $value): void
403403
* @param string $expected
404404
* @param string|int $duration
405405
* @param bool|null $showSeconds
406+
* @param string|null $language
406407
* @throws Exception
407408
*/
408-
public function testHumanDuration(string $expected, string|int $duration, ?bool $showSeconds = null): void
409-
{
410-
self::assertSame($expected, DateTimeHelper::humanDuration($duration, $showSeconds));
409+
public function testHumanDuration(
410+
string $expected,
411+
string|int $duration,
412+
?bool $showSeconds = null,
413+
?string $language = null,
414+
): void {
415+
self::assertSame($expected, DateTimeHelper::humanDuration($duration, $showSeconds, $language));
411416
}
412417

413418
/**
@@ -871,6 +876,8 @@ public function humanDurationDataProvider(): array
871876
['27 minutes', 'PT10M999S'],
872877
['0 seconds', 0],
873878
['less than a minute', 0, false],
879+
['1,000 years', 'P1000Y', false],
880+
['1 000 ans', 'P1000Y', false, 'fr'],
874881
];
875882
}
876883

0 commit comments

Comments
 (0)