Browse Source

added \DateTimeHelper::parse()

Fabian Peter Hammerle 7 years ago
parent
commit
b144bf5fff
2 changed files with 128 additions and 38 deletions
  1. 38 0
      DateTimeHelper.php
  2. 90 38
      tests/DateTimeHelperTest.php

+ 38 - 0
DateTimeHelper.php

@@ -20,4 +20,42 @@ class DateTimeHelper
             throw new \InvalidArgumentException('expected integer or null');
         }
     }
+
+    /**
+     * @param string|null $text
+     * @return DatePeriod|null
+     */
+    public static function parse($text)
+    {
+        if($text === null) {
+            return null;
+        } else {
+            if(preg_match(
+                    '/^(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})'
+                        .'([ T](?P<h>\d{2}):(?P<i>\d{2}):(?P<s>\d{2}))?$/',
+                    $text,
+                    $attr
+                    )) {
+                $start = new \DateTime();
+                $start->setDate($attr['y'], $attr['m'], $attr['d']);
+                $start->setTime(
+                    isset($attr['h']) ? $attr['h'] : 0,
+                    isset($attr['i']) ? $attr['i'] : 0,
+                    isset($attr['s']) ? $attr['s'] : 0
+                    );
+                if(isset($attr['h'])) {
+                    $interval = new \DateInterval('PT1S');
+                } else {
+                    $interval = new \DateInterval('P1D');
+                }
+                $end = clone $start;
+                $end->add($interval);
+                return new \DatePeriod($start, $interval, $end);
+            } else {
+                throw new \InvalidArgumentException(
+                    sprintf("could not parse string '%s'", $text)
+                    );
+            }
+        }
+    }
 }

+ 90 - 38
tests/DateTimeHelperTest.php

@@ -6,67 +6,119 @@ use fphammerle\helpers\DateTimeHelper;
 
 class DateTimeHelperTest extends \PHPUnit_Framework_TestCase
 {
-    public function testTimestampToDateTimeZero()
+    public function timestampToDateTimeProvider()
     {
-        $this->assertEquals(
-            0,
-            DateTimeHelper::timestampToDateTime(0)->getTimestamp()
-            );
+        return [
+            [null, null],
+            [0, new \DateTime('1970-01-01 00:00:00', new \DateTimeZone('UTC'))],
+            [0, new \DateTime('1970-01-01 01:00:00', new \DateTimeZone('Europe/Vienna'))],
+            [1234567890, new \DateTime('2009-02-13 23:31:30', new \DateTimeZone('UTC'))],
+            [1234567890, new \DateTime('2009-02-14 00:31:30', new \DateTimeZone('Europe/Vienna'))],
+            [-3600, new \DateTime('1970-01-01 00:00:00', new \DateTimeZone('Europe/Vienna'))],
+            ];
     }
 
-    public function testTimestampToDateTimeCompareUTC()
+    /**
+     * @dataProvider timestampToDateTimeProvider
+     */
+    public function testTimestampToDateTime($timestamp, $expected_datetime)
     {
-        $created = DateTimeHelper::timestampToDateTime(1234567890);
-        $expected = new \DateTime('2009-02-13 23:31:30', new \DateTimeZone('UTC'));
-        $this->assertEquals($created->getTimestamp(), $expected->getTimestamp());
+        $generated_datetime = DateTimeHelper::timestampToDateTime($timestamp);
+        $this->assertEquals($expected_datetime, $generated_datetime);
     }
 
-    public function testTimestampToDateTimeCompareLocal()
+    public function timestampToDateTimeDefaultTimezoneProvider()
     {
-        $created = DateTimeHelper::timestampToDateTime(1234567890);
-        $expected = new \DateTime('2009-02-14 00:31:30', new \DateTimeZone('Europe/Vienna'));
-        $this->assertEquals($created->getTimestamp(), $expected->getTimestamp());
+        return [
+            ['UTC', 100],
+            ['Europe/Vienna', 0],
+            ['Europe/Vienna', -100],
+            ['Europe/Vienna', 100],
+            ['Europe/London', 3600],
+            ['US/Pacific', 3600],
+            ];
     }
 
-    public function testTimestampToDateTimeSetLocal()
+    /**
+     * @dataProvider timestampToDateTimeDefaultTimezoneProvider
+     */
+    public function testTimestampToDateTimeDefaultTimezone($timezone, $timestamp)
     {
-        date_default_timezone_set('Europe/Vienna');
-        $this->assertEquals(
-            DateTimeHelper::timestampToDateTime(123456)->getTimestamp(),
-            123456
-            );
+        date_default_timezone_set($timezone);
+        $generated_datetime = DateTimeHelper::timestampToDateTime($timestamp);
+        $this->assertSame($timestamp, $generated_datetime->getTimestamp());
     }
 
-    public function testTimestampToDateTimeSetUTC()
+    public function parseProvider()
     {
-        date_default_timezone_set('UTC');
-        $this->assertEquals(
-            DateTimeHelper::timestampToDateTime(123456)->getTimestamp(),
-            123456
-            );
+        return [
+            [null, 'UTC', null],
+            [null, 'US/Pacific', null],
+            ['2016-08-02', 'UTC', new \DatePeriod(
+                new \DateTime('2016-08-02T00:00:00Z'),
+                new \DateInterval('P1D'),
+                new \DateTime('2016-08-03T00:00:00Z')
+                )],
+            ['2016-08-02', 'Europe/Vienna', new \DatePeriod(
+                new \DateTime('2016-08-02T00:00:00+02:00'),
+                new \DateInterval('P1D'),
+                new \DateTime('2016-08-03T00:00:00+02:00')
+                )],
+            ['2016-08-02', 'Europe/Vienna', new \DatePeriod(
+                new \DateTime('2016-08-01T22:00:00Z'),
+                new \DateInterval('P1D'),
+                new \DateTime('2016-08-02T22:00:00Z')
+                )],
+            ['2016-08-02 15:52:13', 'UTC', new \DatePeriod(
+                 new \DateTime('2016-08-02T15:52:13Z'),
+                 new \DateInterval('PT1S'),
+                 new \DateTime('2016-08-02T15:52:14Z')
+                 )],
+            ['2016-08-02 15:52:13', 'Europe/Vienna', new \DatePeriod(
+                 new \DateTime('2016-08-02T15:52:13+02:00'),
+                 new \DateInterval('PT1S'),
+                 new \DateTime('2016-08-02T15:52:14+02:00')
+                 )],
+            ['2016-08-02 15:52:13', 'Europe/Vienna', new \DatePeriod(
+                 new \DateTime('2016-08-02T13:52:13Z'),
+                 new \DateInterval('PT1S'),
+                 new \DateTime('2016-08-02T13:52:14Z')
+                 )],
+            ['2016-08-02T15:52:13', 'US/Pacific', new \DatePeriod(
+                 new \DateTime('2016-08-02T15:52:13-07:00'),
+                 new \DateInterval('PT1S'),
+                 new \DateTime('2016-08-02T15:52:14-07:00')
+                 )],
+            ];
     }
 
-    public function testTimestampToDateTimeNull()
+    /**
+     * @dataProvider parseProvider
+     */
+    public function testParse($text, $timezone, $expected)
     {
-        $this->assertEquals(
-            DateTimeHelper::timestampToDateTime(null),
-            null
-            );
+        date_default_timezone_set($timezone);
+        $this->assertEquals($expected, DateTimeHelper::parse($text));
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    public function testTimestampToDateInvalidArgumentFloat()
+    public function parseInvalidArgumentProvider()
     {
-        DateTimeHelper::timestampToDateTime(1.23);
+        return [
+            ['     '],
+            [''],
+            ['2016--12'],
+            ['2016-10-12 08:20#01'],
+            [1],
+            [false],
+            ];
     }
 
     /**
-     * @expectedException InvalidArgumentException
+     * @dataProvider parseInvalidArgumentProvider
+     * @expectedException \InvalidArgumentException
      */
-    public function testTimestampToDateInvalidArgumentString()
+    public function testParseInvalidArgument($text)
     {
-        DateTimeHelper::timestampToDateTime('');
+        DateTimeHelper::parse($text);
     }
 }