diff --git a/lib/Horde/Date.php b/lib/Horde/Date.php index f4c62be..3e061d8 100644 --- a/lib/Horde/Date.php +++ b/lib/Horde/Date.php @@ -1543,7 +1543,7 @@ protected function _initializeFromArray($date) protected function _initializeFromObject($date) { - if ($date instanceof DateTime) { + if ($date instanceof DateTimeInterface) { $this->_year = (int) $date->format('Y'); $this->_month = (int) $date->format('m'); $this->_mday = (int) $date->format('d'); @@ -1551,19 +1551,25 @@ protected function _initializeFromObject($date) $this->_min = (int) $date->format('i'); $this->_sec = (int) $date->format('s'); $this->_initializeTimezone($date->getTimezone()->getName()); - } else { - $is_horde_date = $date instanceof Horde_Date; + + return; + } + + if ($date instanceof Horde_Date) { foreach (['year', 'month', 'mday', 'hour', 'min', 'sec'] as $key) { - if ($is_horde_date || isset($date->$key)) { - $this->{'_' . $key} = (int) $date->$key; - } + $this->{'_' . $key} = (int) $date->$key; } - if (!$is_horde_date) { - $this->_correct(); - } else { - $this->_initializeTimezone($date->timezone); + $this->_initializeTimezone($date->timezone); + + return; + } + + foreach (['year', 'month', 'mday', 'hour', 'min', 'sec'] as $key) { + if (isset($date->$key)) { + $this->{'_' . $key} = (int) $date->$key; } } + $this->_correct(); } protected function _initializeTimezone($timezone) diff --git a/test/Unnamespaced/DateTest.php b/test/Unnamespaced/DateTest.php index a27ff56..6534ba6 100644 --- a/test/Unnamespaced/DateTest.php +++ b/test/Unnamespaced/DateTest.php @@ -12,13 +12,14 @@ use date_default_timezone_get; use date_default_timezone_set; use DateTime; +use DateTimeImmutable; use DateTimeZone; +use Horde\Date\Format; use Horde_Date; use Horde_Date_Span; use PHPUnit\Framework\TestCase; use stdClass; use Horde_Date_Exception; -use Horde\Date\Format; /** * @category Horde @@ -76,6 +77,34 @@ public function testConstructor() $date = new Horde_Date($dt); $this->assertEquals('2011-12-10 03:05:06', (string) $date); + $dti = new DateTimeImmutable('2026-06-23 12:00:00', new DateTimeZone('UTC')); + $date = new Horde_Date($dti); + $this->assertEquals(2026, $date->year); + $this->assertEquals(6, $date->month); + $this->assertEquals(23, $date->mday); + $this->assertEquals(12, $date->hour); + $this->assertEquals(0, $date->min); + $this->assertEquals(0, $date->sec); + $this->assertEquals('UTC', $date->timezone); + + /* DateTimeImmutable with a non-UTC timezone must preserve the zone. */ + $dti = new DateTimeImmutable('2026-06-23 12:00:00', new DateTimeZone('America/New_York')); + $date = new Horde_Date($dti); + $this->assertEquals('2026-06-23 12:00:00', (string) $date); + $this->assertEquals('America/New_York', $date->timezone); + + $parsed = Format::parseDateTime( + '23.06.2026 12:00', + '%d.%m.%Y', + 'HH:mm', + 'de_DE' + ); + $date = new Horde_Date($parsed->toDateTimeImmutable()); + $this->assertEquals(2026, $date->year); + $this->assertEquals(6, $date->month); + $this->assertEquals(23, $date->mday); + $this->assertGreaterThan(0, $date->timestamp()); + // Test creating Horde_Date from a string that will use DateTime // internally to parse the date. $date = new Horde_Date('2014-03-20 5:00PM');