MDL-66147 core: add get_time_interval_string()
authorJake Dallimore <jake@moodle.com>
Tue, 6 Aug 2019 08:27:26 +0000 (16:27 +0800)
committerJake Dallimore <jake@moodle.com>
Mon, 12 Aug 2019 01:35:51 +0000 (09:35 +0800)
Returns a formatted string representation of the difference between two
timestamps, defaulting to 'Xd Xh Xm' format, but supporting custom
format strings containing any chars from:
https://www.php.net/manual/en/dateinterval.format.php.

lang/en/moodle.php
lib/moodlelib.php
lib/tests/moodlelib_test.php

index 25e9c45..eb9dea1 100644 (file)
@@ -1638,6 +1638,7 @@ $string['rejectdots'] = 'Reject...';
 $string['relativedatesmode'] = 'Relative dates mode';
 $string['relativedatesmode_help'] = 'Display course or activity dates relative to the user\'s start date in the course.<br />The user\'s course start date will be their enrolment start date, unless they are enrolled before the course begins in which case their start date will be the course start date.<br/><strong>WARNING: This is an experimental feature and not all activities may support it. Once the course has been created, this course setting can no longer be changed.</strong>';
 $string['relativedatesmode_warning'] = '<strong>Warning:</strong> Relative dates mode cannot be changed once the course has been created.';
+$string['relativedatestimediffformat'] = '%ad %hh %im';
 $string['reload'] = 'Reload';
 $string['remoteappuser'] = 'Remote {$a} User';
 $string['remove'] = 'Remove';
index 5b2f3d1..3e86491 100644 (file)
@@ -2374,6 +2374,29 @@ function usertime($date, $timezone=99) {
     return $date - $userdate->getOffset() + $dst;
 }
 
+/**
+ * Get a formatted string representation of an interval between two unix timestamps.
+ *
+ * E.g.
+ * $intervalstring = get_time_interval_string(12345600, 12345660);
+ * Will produce the string:
+ * '0d 0h 1m'
+ *
+ * @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.
+ * @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 {
+    $dtdate = new DateTime();
+    $dtdate->setTimeStamp($time1);
+    $dtdate2 = new DateTime();
+    $dtdate2->setTimeStamp($time2);
+    $interval = $dtdate2->diff($dtdate);
+    $format = empty($format) ? get_string('relativedatestimediffformat', 'moodle') : $format;
+    return $interval->format($format);
+}
+
 /**
  * Given a time, return the GMT timestamp of the most recent midnight
  * for the current user.
index 86a97c5..b65af40 100644 (file)
@@ -4457,4 +4457,83 @@ class core_moodlelib_testcase extends advanced_testcase {
 
         $this->assertContains('passwords cannot be reset on this site', quoted_printable_decode($result[0]->body));
     }
+
+    /**
+     * Test the get_time_interval_string for a range of inputs.
+     *
+     * @dataProvider get_time_interval_string_provider
+     * @param int $time1 the time1 param.
+     * @param int $time2 the time2 param.
+     * @param string|null $format the format param.
+     * @param string $expected the expected string.
+     */
+    public function test_get_time_interval_string(int $time1, int $time2, ?string $format, string $expected) {
+        if (is_null($format)) {
+            $this->assertEquals($expected, get_time_interval_string($time1, $time2));
+        } else {
+            $this->assertEquals($expected, get_time_interval_string($time1, $time2, $format));
+        }
+    }
+
+    /**
+     * Data provider for the test_get_time_interval_string() method.
+     */
+    public function get_time_interval_string_provider() {
+        return [
+            'Time is after the reference time by 1 minute, omitted format' => [
+                'time1' => 12345660,
+                'time2' => 12345600,
+                'format' => null,
+                'expected' => '0d 0h 1m'
+            ],
+            'Time is before the reference time by 1 minute, omitted format' => [
+                'time1' => 12345540,
+                'time2' => 12345600,
+                'format' => null,
+                'expected' => '0d 0h 1m'
+            ],
+            'Time is equal to the reference time, omitted format' => [
+                'time1' => 12345600,
+                'time2' => 12345600,
+                'format' => null,
+                'expected' => '0d 0h 0m'
+            ],
+            'Time is after the reference time by 1 minute, empty string format' => [
+                'time1' => 12345660,
+                'time2' => 12345600,
+                'format' => '',
+                'expected' => '0d 0h 1m'
+            ],
+            'Time is before the reference time by 1 minute, empty string format' => [
+                'time1' => 12345540,
+                'time2' => 12345600,
+                'format' => '',
+                'expected' => '0d 0h 1m'
+            ],
+            'Time is equal to the reference time, empty string format' => [
+                'time1' => 12345600,
+                'time2' => 12345600,
+                'format' => '',
+                'expected' => '0d 0h 0m'
+            ],
+            'Time is after the reference time by 1 minute, custom format' => [
+                'time1' => 12345660,
+                'time2' => 12345600,
+                'format' => '%R%adays %hhours %imins',
+                'expected' => '+0days 0hours 1mins'
+            ],
+            'Time is before the reference time by 1 minute, custom format' => [
+                'time1' => 12345540,
+                'time2' => 12345600,
+                'format' => '%R%adays %hhours %imins',
+                'expected' => '-0days 0hours 1mins'
+            ],
+            'Time is equal to the reference time, custom format' => [
+                'time1' => 12345600,
+                'time2' => 12345600,
+                'format' => '%R%adays %hhours %imins',
+                'expected' => '+0days 0hours 0mins'
+            ],
+        ];
+    }
 }