Skip to content

Commit

Permalink
MDL-74810 core: get_time_interval_string() improvements
Browse files Browse the repository at this point in the history
* Add parameter to drop zero time units. So a time interval like
  "3d 0h 0s" will be returned as "3d" only.
* Add parameter to display full format for time units. E.g. Instead of
  "3d 2h", it will be returned as "3 days 2 hours"
* Deprecate unused dateintervaldayshoursmins langconfig string.
  • Loading branch information
junpataleta committed Aug 28, 2023
1 parent 9bfcd77 commit ec90b34
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 5 deletions.
1 change: 1 addition & 0 deletions lang/en/deprecated.txt
Expand Up @@ -92,3 +92,4 @@ devicedetectregexexpression,core_admin
devicedetectregexvalue,core_admin
modshowcmtitle,core
makeavailablecmtitle,core
dateintervaldayshoursmins,core_langconfig
131 changes: 130 additions & 1 deletion lang/en/langconfig.php
Expand Up @@ -26,7 +26,133 @@
$string['am'] = 'am';
$string['amcaps'] = 'AM';
$string['backupnameformat'] = '%Y%m%d-%H%M';
$string['dateintervaldayshoursmins'] = '%ad %hh %im'; // See https://www.php.net/manual/en/dateinterval.format.php for format.
// See https://www.php.net/manual/en/dateinterval.format.php for format used in dateintervalxx strings.
$string['dateintervalday'] = '%ad';
$string['dateintervaldayfull'] = '%a days';
$string['dateintervaldayhr'] = '%ad %hh';
$string['dateintervaldayhrfull'] = '%a days %h hours';
$string['dateintervaldayhrmin'] = '%ad %hh %im';
$string['dateintervaldayhrminfull'] = '%a days %h hours %i minutes';
$string['dateintervaldayhrminsec'] = '%ad %hh %im %ss';
$string['dateintervaldayhrminsecfull'] = '%a days %h hours %i minutes %s seconds';
$string['dateintervaldayhrsec'] = '%ad %hh %ss';
$string['dateintervaldayhrsecfull'] = '%a days %h hours %s seconds';
$string['dateintervaldaymin'] = '%ad %im';
$string['dateintervaldayminfull'] = '%a days %i minutes';
$string['dateintervaldayminsec'] = '%ad %im %ss';
$string['dateintervaldayminsecfull'] = '%a days %i minutes %s seconds';
$string['dateintervaldaysec'] = '%ad %ss';
$string['dateintervaldaysecfull'] = '%a days %s seconds';
$string['dateintervalhr'] = '%hh';
$string['dateintervalhrfull'] = '%h hours';
$string['dateintervalhrmin'] = '%hh %im';
$string['dateintervalhrminfull'] = '%h hours %i minutes';
$string['dateintervalhrminsec'] = '%hh %im %ss';
$string['dateintervalhrminsecfull'] = '%h hours %i minutes %s seconds';
$string['dateintervalhrsec'] = '%hh %ss';
$string['dateintervalhrsecfull'] = '%h hours %s seconds';
$string['dateintervalmin'] = '%im';
$string['dateintervalminfull'] = '%i minutes';
$string['dateintervalminsec'] = '%im %ss';
$string['dateintervalminsecfull'] = '%i minutes %s seconds';
$string['dateintervalmo'] = '%mmo';
$string['dateintervalmoday'] = '%mmo %ad';
$string['dateintervalmodayfull'] = '%m months %a days';
$string['dateintervalmodayhr'] = '%mmo %ad %hh';
$string['dateintervalmodayhrfull'] = '%m months %a days %h hours';
$string['dateintervalmodayhrmin'] = '%mmo %ad %hh %im';
$string['dateintervalmodayhrminfull'] = '%m months %a days %h hours %i minutes';
$string['dateintervalmodayhrminsec'] = '%mmo %ad %hh %im %ss';
$string['dateintervalmodayhrminsecfull'] = '%m months %a days %h hours %i minutes %s seconds';
$string['dateintervalmodayhrsec'] = '%mmo %ad %hh %ss';
$string['dateintervalmodayhrsecfull'] = '%m months %a days %h hours %s seconds';
$string['dateintervalmodaymin'] = '%mmo %ad %im';
$string['dateintervalmodayminfull'] = '%m months %a days %i minutes';
$string['dateintervalmodayminsec'] = '%mmo %ad %im %ss';
$string['dateintervalmodayminsecfull'] = '%m months %a days %i minutes %s seconds';
$string['dateintervalmodaysec'] = '%mmo %ad %ss';
$string['dateintervalmodaysecfull'] = '%m months %a days %s seconds';
$string['dateintervalmofull'] = '%m months';
$string['dateintervalmohr'] = '%mmo %hh';
$string['dateintervalmohrfull'] = '%m months %h hours';
$string['dateintervalmohrmin'] = '%mmo %hh %im';
$string['dateintervalmohrminfull'] = '%m months %h hours %i minutes';
$string['dateintervalmohrminsec'] = '%mmo %hh %im %ss';
$string['dateintervalmohrminsecfull'] = '%m months %h hours %i minutes %s seconds';
$string['dateintervalmohrsec'] = '%mmo %hh %ss';
$string['dateintervalmohrsecfull'] = '%m months %h hours %s seconds';
$string['dateintervalmomin'] = '%mmo %im';
$string['dateintervalmominfull'] = '%m months %i minutes';
$string['dateintervalmominsec'] = '%mmo %im %ss';
$string['dateintervalmominsecfull'] = '%m months %i minutes %s seconds';
$string['dateintervalmosec'] = '%mmo %ss';
$string['dateintervalmosecfull'] = '%m months %s seconds';
$string['dateintervalsec'] = '%ss';
$string['dateintervalsecfull'] = '%s seconds';
$string['dateintervalyr'] = '%yy';
$string['dateintervalyrday'] = '%yy %ad';
$string['dateintervalyrdayfull'] = '%y years %a days';
$string['dateintervalyrdayhr'] = '%yy %ad %hh';
$string['dateintervalyrdayhrfull'] = '%y years %a days %h hours';
$string['dateintervalyrdayhrmin'] = '%yy %ad %hh %im';
$string['dateintervalyrdayhrminfull'] = '%y years %a days %h hours %i minutes';
$string['dateintervalyrdayhrminsec'] = '%yy %ad %hh %im %ss';
$string['dateintervalyrdayhrminsecfull'] = '%y years %a days %h hours %i minutes %s seconds';
$string['dateintervalyrdayhrsec'] = '%yy %ad %hh %ss';
$string['dateintervalyrdayhrsecfull'] = '%y years %a days %h hours %s seconds';
$string['dateintervalyrdaymin'] = '%yy %ad %im';
$string['dateintervalyrdayminfull'] = '%y years %a days %i minutes';
$string['dateintervalyrdayminsec'] = '%yy %ad %im %ss';
$string['dateintervalyrdayminsecfull'] = '%y years %a days %i minutes %s seconds';
$string['dateintervalyrdaysec'] = '%yy %ad %ss';
$string['dateintervalyrdaysecfull'] = '%y years %a days %s seconds';
$string['dateintervalyrfull'] = '%y years';
$string['dateintervalyrhr'] = '%yy %hh';
$string['dateintervalyrhrfull'] = '%y years %h hours';
$string['dateintervalyrhrmin'] = '%yy %hh %im';
$string['dateintervalyrhrminfull'] = '%y years %h hours %i minutes';
$string['dateintervalyrhrminsec'] = '%yy %hh %im %ss';
$string['dateintervalyrhrminsecfull'] = '%y years %h hours %i minutes %s seconds';
$string['dateintervalyrhrsec'] = '%yy %hh %ss';
$string['dateintervalyrhrsecfull'] = '%y years %h hours %s seconds';
$string['dateintervalyrmin'] = '%yy %im';
$string['dateintervalyrminfull'] = '%y years %i minutes';
$string['dateintervalyrminsec'] = '%yy %im %ss';
$string['dateintervalyrminsecfull'] = '%y years %i minutes %s seconds';
$string['dateintervalyrmo'] = '%yy %mmo';
$string['dateintervalyrmoday'] = '%yy %mmo %ad';
$string['dateintervalyrmodayfull'] = '%y years %m months %a days';
$string['dateintervalyrmodayhr'] = '%yy %mmo %ad %hh';
$string['dateintervalyrmodayhrfull'] = '%y years %m months %a days %h hours';
$string['dateintervalyrmodayhrmin'] = '%yy %mmo %ad %hh %im';
$string['dateintervalyrmodayhrminfull'] = '%y years %m months %a days %h hours %i minutes';
$string['dateintervalyrmodayhrminsec'] = '%yy %mmo %ad %hh %im %ss';
$string['dateintervalyrmodayhrminsecfull'] = '%y years %m months %a days %h hours %i minutes %s seconds';
$string['dateintervalyrmodayhrsec'] = '%yy %mmo %ad %hh %ss';
$string['dateintervalyrmodayhrsecfull'] = '%y years %m months %a days %h hours %s seconds';
$string['dateintervalyrmodaymin'] = '%yy %mmo %ad %im';
$string['dateintervalyrmodayminfull'] = '%y years %m months %a days %i minutes';
$string['dateintervalyrmodayminsec'] = '%yy %mmo %ad %im %ss';
$string['dateintervalyrmodayminsecfull'] = '%y years %m months %a days %i minutes %s seconds';
$string['dateintervalyrmodaysec'] = '%yy %mmo %ad %ss';
$string['dateintervalyrmodaysecfull'] = '%y years %m months %a days %s seconds';
$string['dateintervalyrmofull'] = '%y years %m months';
$string['dateintervalyrmohr'] = '%yy %mmo %hh';
$string['dateintervalyrmohrfull'] = '%y years %m months %h hours';
$string['dateintervalyrmohrmin'] = '%yy %mmo %hh %im';
$string['dateintervalyrmohrminfull'] = '%y years %m months %h hours %i minutes';
$string['dateintervalyrmohrminsec'] = '%yy %mmo %hh %im %ss';
$string['dateintervalyrmohrminsecfull'] = '%y years %m months %h hours %i minutes %s seconds';
$string['dateintervalyrmohrsec'] = '%yy %mmo %hh %ss';
$string['dateintervalyrmohrsecfull'] = '%y years %m months %h hours %s seconds';
$string['dateintervalyrmomin'] = '%yy %mmo %im';
$string['dateintervalyrmominfull'] = '%y years %m months %i minutes';
$string['dateintervalyrmominsec'] = '%yy %mmo %im %ss';
$string['dateintervalyrmominsecfull'] = '%y years %m months %i minutes %s seconds';
$string['dateintervalyrmosec'] = '%yy %mmo %ss';
$string['dateintervalyrmosecfull'] = '%y years %m months %s seconds';
$string['dateintervalyrsec'] = '%yy %ss';
$string['dateintervalyrsecfull'] = '%y years %s seconds';
$string['decsep'] = '.';
$string['firstdayofweek'] = '1';
$string['iso6391'] = 'en';
Expand Down Expand Up @@ -71,3 +197,6 @@
$string['thislanguage'] = 'English';
$string['thislanguageint'] = 'English';
$string['thousandssep'] = ',';

// Deprecated since Moodle 4.3.
$string['dateintervaldayshoursmins'] = '%ad %hh %im';
39 changes: 37 additions & 2 deletions lib/moodlelib.php
Expand Up @@ -2441,15 +2441,50 @@ function usertime($date, $timezone=99) {
* @param int $time1 unix timestamp
* @param int $time2 unix timestamp
* @param string $format string (can be lang string) containing format chars: https://www.php.net/manual/en/dateinterval.format.php.
* @param bool $dropzeroes If format is not provided and this is set to true, do not include zero time units.
* e.g. a duration of 3 days and 2 hours will be displayed as '3d 2h' instead of '3d 2h 0s'
* @param bool $fullformat If format is not provided and this is set to true, display time units in full format.
* e.g. instead of showing "3d", "3 days" will be returned.
* @return string the formatted string describing the time difference, e.g. '10d 11h 45m'.
*/
function get_time_interval_string(int $time1, int $time2, string $format = ''): string {
function get_time_interval_string(int $time1, int $time2, string $format = '',
bool $dropzeroes = false, bool $fullformat = false): string {
$dtdate = new DateTime();
$dtdate->setTimeStamp($time1);
$dtdate2 = new DateTime();
$dtdate2->setTimeStamp($time2);
$interval = $dtdate2->diff($dtdate);
$format = empty($format) ? get_string('dateintervaldayshoursmins', 'langconfig') : $format;

if (empty(trim($format))) {
// Default to this key.
$formatkey = 'dateintervaldayhrmin';

if ($dropzeroes) {
$units = [
'y' => 'yr',
'm' => 'mo',
'd' => 'day',
'h' => 'hr',
'i' => 'min',
's' => 'sec',
];
$formatunits = [];
foreach ($units as $key => $unit) {
if (empty($interval->$key)) {
continue;
}
$formatunits[] = $unit;
}
if (!empty($formatunits)) {
$formatkey = 'dateinterval' . implode("", $formatunits);
}
}

if ($fullformat) {
$formatkey .= 'full';
}
$format = get_string($formatkey, 'langconfig');
}
return $interval->format($format);
}

Expand Down
39 changes: 37 additions & 2 deletions lib/tests/moodlelib_test.php
Expand Up @@ -4646,12 +4646,16 @@ public function test_send_password_change_info() {
* @param int $time2 the time2 param.
* @param string|null $format the format param.
* @param string $expected the expected string.
* @param bool $dropzeroes the value passed for the `$dropzeros` param.
* @param bool $fullformat the value passed for the `$fullformat` param.
* @covers \get_time_interval_string
*/
public function test_get_time_interval_string(int $time1, int $time2, ?string $format, string $expected) {
public function test_get_time_interval_string(int $time1, int $time2, ?string $format, string $expected,
bool $dropzeroes = false, bool $fullformat = false) {
if (is_null($format)) {
$this->assertEquals($expected, get_time_interval_string($time1, $time2));
} else {
$this->assertEquals($expected, get_time_interval_string($time1, $time2, $format));
$this->assertEquals($expected, get_time_interval_string($time1, $time2, $format, $dropzeroes, $fullformat));
}
}

Expand Down Expand Up @@ -4714,6 +4718,37 @@ public function get_time_interval_string_provider() {
'format' => '%R%adays %hhours %imins',
'expected' => '+0days 0hours 0mins'
],
'Default format, time is after the reference time by 1 minute, drop zeroes, short form' => [
'time1' => 12345660,
'time2' => 12345600,
'format' => '',
'expected' => '1m',
'dropzeroes' => true,
],
'Default format, time is after the reference time by 1 minute, drop zeroes, full form' => [
'time1' => 12345660,
'time2' => 12345600,
'format' => '',
'expected' => '1 minutes',
'dropzeroes' => true,
'fullformat' => true,
],
'Default format, time is after the reference time by 1 minute, retain zeroes, full form' => [
'time1' => 12345660,
'time2' => 12345600,
'format' => '',
'expected' => '0 days 0 hours 1 minutes',
'dropzeroes' => false,
'fullformat' => true,
],
'Empty string format, time is after the reference time by 1 minute, retain zeroes, full form' => [
'time1' => 12345660,
'time2' => 12345600,
'format' => ' ',
'expected' => '0 days 0 hours 1 minutes',
'dropzeroes' => false,
'fullformat' => true,
],
];
}

Expand Down
3 changes: 3 additions & 0 deletions lib/upgrade.txt
Expand Up @@ -140,6 +140,9 @@ being forced open in all behat tests.
* A new parameter $compactmode has been added to the recaptcha_get_challenge_html() to define whether the reCaptcha element should be displayed in the compact mode or not.
Default value is false.
* A new native event in the `core_filters/events` AMD module eventTypes.filterContentRenderingComplete has been created to determine when the filter is complete the rendering.
* New parameters for \get_time_interval_string():
- `$dropzeroes` - Passing `true` will exclude zero date/time units from the output.
- `$fullformat` - Passing `true` will return date/time units in full format (e.g. `1 day` instead of `1d`).

=== 4.2 ===

Expand Down

0 comments on commit ec90b34

Please sign in to comment.