Browse Source

DateTimeHelper::parse(): support iso strings specifying year

Fabian Peter Hammerle 7 years ago
parent
commit
8b110a01da
2 changed files with 33 additions and 11 deletions
  1. 20 8
      DateTimeHelper.php
  2. 13 3
      tests/DateTimeHelperTest.php

+ 20 - 8
DateTimeHelper.php

@@ -4,7 +4,7 @@ namespace fphammerle\helpers;
 
 class DateTimeHelper
 {
-    const _timezone_iso_pattern = '(Z|[\+-]\d{2}.\d{2})';
+    const _timezone_iso_pattern = '(?P<tz>Z|[\+-]\d{2}.\d{2})';
 
     /**
      * @param integer|null $timestamp unix timestamp
@@ -32,13 +32,9 @@ class DateTimeHelper
         if($text === null) {
             return null;
         } else {
-            if(preg_match('/^\d{4}-(?P<m>\d{2})( ?' . self::_timezone_iso_pattern . ')?$/', $text, $attr)) {
-                $start = new \DateTime($text);
-                $interval = new \DateInterval('P1M');
-                return new \DatePeriod($start, $interval, 0);
-            } elseif(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}))?)?)?'
+            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}))?)?'
                         . '(' . self::_timezone_iso_pattern . ')?$/',
                     $text,
                     $attr
@@ -52,6 +48,22 @@ class DateTimeHelper
                     $interval = new \DateInterval('P1D');
                 }
                 return new \DatePeriod($start, $interval, 0);
+            } elseif(preg_match('/^\d{4}-(?P<m>\d{2})( ?' . self::_timezone_iso_pattern . ')?$/', $text, $attr)) {
+                return new \DatePeriod(
+                    new \DateTime($text),
+                    new \DateInterval('P1M'),
+                    0
+                    );
+            } elseif(preg_match('/^(?P<y>\d{4})( ?' . self::_timezone_iso_pattern . ')?$/', $text, $attr)) {
+                return new \DatePeriod(
+                    new \DateTime(sprintf(
+                        '%s-01-01 %s',
+                        $attr['y'],
+                        isset($attr['tz']) ? $attr['tz'] : ''
+                        )),
+                    new \DateInterval('P1Y'),
+                    0
+                    );
             } else {
                 throw new \InvalidArgumentException(
                     sprintf("could not parse string '%s'", $text)

+ 13 - 3
tests/DateTimeHelperTest.php

@@ -58,9 +58,20 @@ class DateTimeHelperTest extends \PHPUnit_Framework_TestCase
             // null
             [null, 'UTC', null],
             [null, 'US/Pacific', null],
+            // year without timezone
+            ['1900', 'UTC',           new DP(new DT('1900-01-01T00:00:00Z'),      new DI('P1Y'), 0)],
+            ['0014', 'Europe/Vienna', new DP(new DT('0014-01-01T00:00:00+01:00'), new DI('P1Y'), 0)],
+            ['2016', 'US/Pacific',    new DP(new DT('2016-01-01T00:00:00-08:00'), new DI('P1Y'), 0)],
+            // year with timezone
+            ['1900Z',       'US/Pacific',    new DP(new DT('1900-01-01T00:00:00Z'),      new DI('P1Y'), 0)],
+            ['2016Z',       'Europe/Vienna', new DP(new DT('2016-01-01T00:00:00Z'),      new DI('P1Y'), 0)],
+            ['2016+00:00',  'Europe/Vienna', new DP(new DT('2016-01-01T00:00:00Z'),      new DI('P1Y'), 0)],
+            ['2016+02:00',  'US/Pacific',    new DP(new DT('2016-01-01T00:00:00+02:00'), new DI('P1Y'), 0)],
+            ['0000 +02:05', 'US/Pacific',    new DP(new DT('0000-01-01T00:00:00+02:05'), new DI('P1Y'), 0)],
+            ['2016-08:00',  'UTC',           new DP(new DT('2016-01-01T00:00:00-08:00'), new DI('P1Y'), 0)],
+            ['2016 -08:00', 'UTC',           new DP(new DT('2016-01-01T00:00:00-08:00'), new DI('P1Y'), 0)],
             // month without timezone
             ['2016-08', 'UTC',           new DP(new DT('2016-08-01T00:00:00Z'),      new DI('P1M'), 0)],
-            ['2016-08', 'UTC',           new DP(new DT('2016-08-01T00:00:00Z'),      new DI('P1M'), 0)],
             ['2016-08', 'Europe/Vienna', new DP(new DT('2016-08-01T00:00:00+02:00'), new DI('P1M'), 0)],
             ['2016-01', 'US/Pacific',    new DP(new DT('2016-01-01T00:00:00-08:00'), new DI('P1M'), 0)],
             // month with timezone
@@ -72,7 +83,6 @@ class DateTimeHelperTest extends \PHPUnit_Framework_TestCase
             ['2016-01 -08:00', 'UTC',           new DP(new DT('2016-01-01T00:00:00-08:00'), new DI('P1M'), 0)],
             // date without timezone
             ['2016-08-02', 'UTC',           new DP(new DT('2016-08-02T00:00:00Z'),      new DI('P1D'), 0)],
-            ['2016-08-02', 'UTC',           new DP(new DT('2016-08-02T00:00:00Z'),      new DI('P1D'), 0)],
             ['2016-08-02', 'Europe/Vienna', new DP(new DT('2016-08-02T00:00:00+02:00'), new DI('P1D'), 0)],
             ['2016-01-02', 'US/Pacific',    new DP(new DT('2016-01-02T00:00:00-08:00'), new DI('P1D'), 0)],
             // date with timezone
@@ -80,7 +90,7 @@ class DateTimeHelperTest extends \PHPUnit_Framework_TestCase
             ['2016-08-02Z',      'Europe/Vienna', new DP(new DT('2016-08-02T00:00:00Z'),      new DI('P1D'), 0)],
             ['2016-01-02+00:00', 'Europe/Vienna', new DP(new DT('2016-01-02T00:00:00Z'),      new DI('P1D'), 0)],
             ['2016-01-02+02:00', 'US/Pacific',    new DP(new DT('2016-01-02T00:00:00+02:00'), new DI('P1D'), 0)],
-            ['2016-01-02-08:00', 'UTC',           new DP(new DT('2016-01-02T00:00:00-08:00'), new DI('P1D'), 0)],
+            ['2016-01-02-08:13', 'UTC',           new DP(new DT('2016-01-02T00:00:00-08:13'), new DI('P1D'), 0)],
             // minute without timezone
             ['2016-08-02 15:52', 'UTC',           new DP(new DT('2016-08-02T15:52:00Z'),      new DI('PT1M'), 0)],
             ['2016-08-02T15:52', 'UTC',           new DP(new DT('2016-08-02T15:52:00Z'),      new DI('PT1M'), 0)],