diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..61f26e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +vendor/ +_site/ +tmp/ +build/ +cache/ +docs/ + +composer.lock + +*DS_Store diff --git a/README b/README index e69de29..76f9f6b 100644 --- a/README +++ b/README @@ -0,0 +1 @@ +Converts between colon formatted time, human-readable time and seconds diff --git a/composer.json b/composer.json new file mode 100755 index 0000000..863cbcd --- /dev/null +++ b/composer.json @@ -0,0 +1,24 @@ +{ + "name": "khill/durations", + "description": "Converts between colon formatted time, human-readable time and seconds.", + "keywords": ["durations", "time", "convert"], + "license": "MIT", + "authors": [ + { + "name" : "Kevin Hill", + "email": "kevinkhill@gmail.com", + "role" : "Developer" + } + ], + "require": { + "php": ">=5.3.0" + }, + "require-dev" : { + "phpunit/phpunit": "4.5.*" + }, + "autoload": { + "psr-4": { + "Khill\\Durations\\" : "src" + } + } +} diff --git a/src/Durations.php b/src/Durations.php new file mode 100755 index 0000000..8b70c40 --- /dev/null +++ b/src/Durations.php @@ -0,0 +1,172 @@ +hours = 0; + $this->minutes = 0; + $this->seconds = 0; + + $this->output = ''; + $this->hoursRegex = '/([0-9]{1,2})\s?(?:h|H)/'; + $this->minutesRegex = '/([0-9]{1,2})\s?(?:m|M)/'; + $this->secondsRegex = '/([0-9]{1,2})\s?(?:s|S)/'; + + if (! is_null($timeStr)) { + $this->parse($timeStr); + } + } + + public function parse($timeStr) + { + $this->reset(); + $this->timeStr = $timeStr; + + if (is_numeric($this->timeStr)) { + $this->seconds = (int) $this->timeStr; + + if ($this->seconds >= 60) { + $this->minutes = (int) floor($this->seconds / 60); + $this->seconds = (int) ($this->seconds - ($this->minutes * 60)); + } + + if ($this->minutes >= 60) { + $this->hours = (int) floor($this->minutes / 60); + $this->minutes = (int) ($this->minutes - ($this->hours * 60)); + } + + return $this; + } else if (preg_match('/\:/', $this->timeStr)) { + $parts = explode(':', $this->timeStr); + + if (count($parts) == 2) { + $this->minutes = (int) $parts[0]; + $this->seconds = (int) $parts[1]; + } else if (count($parts) == 3) { + $this->hours = (int) $parts[0]; + $this->minutes = (int) $parts[1]; + $this->seconds = (int) $parts[2]; + } + + return $this; + } else if (preg_match($this->hoursRegex, $this->timeStr) || + preg_match($this->minutesRegex, $this->timeStr) || + preg_match($this->secondsRegex, $this->timeStr)) + { + if (preg_match($this->hoursRegex, $this->timeStr, $matches)) { + $this->hours = (int) $matches[1]; + } + + if (preg_match($this->minutesRegex, $this->timeStr, $matches)) { + $this->minutes = (int) $matches[1]; + } + + if (preg_match($this->secondsRegex, $this->timeStr, $matches)) { + $this->seconds = (int) $matches[1]; + } + + return $this; + } else { + return false; + } + } + + private function reset() + { + $this->output = ''; + $this->seconds = 0; + $this->minutes = 0; + $this->hours = 0; + } + + private function output() + { + $out = $this->output; + + $this->reset(); + + return $out; + } + + public function toSeconds($timeStr) + { + if (! is_null($timeStr)) { + $this->parse($timeStr); + } + + $this->output = ($this->hours * 60 * 60) + ($this->minutes * 60) + $this->seconds; + + return $this->output(); + } + + public function formatted($timeStr) + { + if (! is_null($timeStr)) { + $this->parse($timeStr); + } + + if ($this->seconds > 0) { + if ($this->seconds < 9 && ($this->minutes > 0 || $this->hours > 0)) { + $this->output .= '0' . $this->seconds; + } else { + $this->output .= $this->seconds; + } + } else { + if ($this->minutes > 0 || $this->hours > 0) { + $this->output = '00'; + } + } + + if ($this->minutes > 0) { + if ($this->minutes < 9 && $this->hours > 0) { + $this->output = '0' . $this->minutes . ':' . $this->output; + } else { + $this->output = $this->minutes . ':' . $this->output; + } + } else { + if ($this->hours > 0) { + $this->output = '00' . ':' . $this->output; + } + } + + if ($this->hours > 0) { + $this->output = $this->hours . ':' . $this->output; + } + + return $this->output(); + } + + public function humanize($timeStr) + { + if (! is_null($timeStr)) { + $this->parse($timeStr); + } + + if ($this->seconds > 0) { + $this->output .= $this->seconds . 's'; + } + + if ($this->minutes > 0) { + $this->output = $this->minutes . 'm ' . $this->output; + } + + if ($this->hours > 0) { + $this->output = $this->hours . 'h ' . $this->output; + } + + return trim($this->output()); + } + +} + diff --git a/tests/DurationsTest.php b/tests/DurationsTest.php new file mode 100755 index 0000000..35d7283 --- /dev/null +++ b/tests/DurationsTest.php @@ -0,0 +1,141 @@ +d = new Durations; + } + + public function secondsSampleData() + { + return [ + [ 1, '1 s'], + [ 1, '1 sec'], + [ 3, '3S'], + [ 7, '7 S'], + [51, '51seconds'], + [ 4, '4 Sec.'], + [15, '15 SEcONDs'] + ]; + } + + /** + * @dataProvider secondsSampleData + */ + public function testGettingValueFromSecondSuffixes($intVal, $secStr) + { + $this->d->parse($secStr); + $this->assertEquals($intVal, $this->d->seconds); + } + + public function minutesSampleData() + { + return [ + [ 1, '1 m'], + [ 4, '4 min'], + [ 6, '6M'], + [14, '14 Ms'], + [31, '31 minutes'], + [ 9, '9Min.'], + [11, '11 MINUTE'] + ]; + } + + /** + * @dataProvider minutesSampleData + */ + public function testGettingValueFromMinuteSuffixes($intVal, $minStr) + { + $this->d->parse($minStr); + $this->assertEquals($intVal, $this->d->minutes); + } + + public function hoursSampleData() + { + return [ + [ 1, '1 h'], + [ 1, '1 hr'], + [ 1, '1H'], + [24, '24 Hrs'], + [ 3, '3hours'], + [ 6, '6HoUr'], + [14, '14 HOURs'] + ]; + } + + /** + * @dataProvider hoursSampleData + */ + public function testGettingValueFromHourSuffixes($intVal, $hrStr) + { + $this->d->parse($hrStr); + $this->assertEquals($intVal, $this->d->hours); + } + + public function testConvertingSecondsToFormattedString() + { + $this->assertEquals('4', $this->d->formatted(4)); + $this->assertEquals('42', $this->d->formatted(42)); + $this->assertEquals('1:02', $this->d->formatted(62)); + $this->assertEquals('1:42', $this->d->formatted(102)); + $this->assertEquals('10:47', $this->d->formatted(647)); + $this->assertEquals('1:00:00', $this->d->formatted(3600)); + $this->assertEquals('1:00:01', $this->d->formatted(3601)); + $this->assertEquals('1:00:11', $this->d->formatted(3611)); + $this->assertEquals('1:01:00', $this->d->formatted(3660)); + $this->assertEquals('1:01:14', $this->d->formatted(3674)); + $this->assertEquals('1:04:25', $this->d->formatted(3865)); + } + + public function testConvertingFormattedStringsToSeconds() + { + $this->assertEquals(4, $this->d->toSeconds('4')); + $this->assertEquals(42, $this->d->toSeconds('42')); + $this->assertEquals(62, $this->d->toSeconds('1:02')); + $this->assertEquals(102, $this->d->toSeconds('1:42')); + $this->assertEquals(647, $this->d->toSeconds('10:47')); + $this->assertEquals(3600, $this->d->toSeconds('1:00:00')); + $this->assertEquals(3601, $this->d->toSeconds('1:00:01')); + $this->assertEquals(3611, $this->d->toSeconds('1:00:11')); + $this->assertEquals(3660, $this->d->toSeconds('1:01:00')); + $this->assertEquals(3674, $this->d->toSeconds('1:01:14')); + $this->assertEquals(3865, $this->d->toSeconds('1:04:25')); + } + + public function testConvertSecondsToHumanizedString() + { + $this->assertEquals('4s', $this->d->humanize(4)); + $this->assertEquals('42s', $this->d->humanize(42)); + $this->assertEquals('1m 2s', $this->d->humanize(62)); + $this->assertEquals('1m 42s', $this->d->humanize(102)); + $this->assertEquals('10m 47s', $this->d->humanize(647)); + $this->assertEquals('1h', $this->d->humanize(3600)); + $this->assertEquals('1h 5s', $this->d->humanize(3605)); + $this->assertEquals('1h 1m', $this->d->humanize(3660)); + $this->assertEquals('1h 1m 5s', $this->d->humanize(3665)); + } + + /** + * @depends testGettingValueFromSecondSuffixes + * @depends testGettingValueFromMinuteSuffixes + * @depends testGettingValueFromHourSuffixes + */ + public function testConvertHumanizedStringToSeconds() + { + $this->assertEquals(4, $this->d->toSeconds('4s')); + $this->assertEquals(42, $this->d->toSeconds('42s')); + $this->assertEquals(72, $this->d->toSeconds('1m 12s')); + $this->assertEquals(102, $this->d->toSeconds('1m 42s')); + $this->assertEquals(647, $this->d->toSeconds('10m 47s')); + $this->assertEquals(3600, $this->d->toSeconds('1h')); + $this->assertEquals(3605, $this->d->toSeconds('1h 5s')); + $this->assertEquals(3660, $this->d->toSeconds('1h 1m')); + $this->assertEquals(3665, $this->d->toSeconds('1h 1m 5s')); + } + +}