<?php
namespace Zend\Stdlib;
use DateTimeZone;
class DateTime extends \DateTime
{
public function __construct($time = 'now', DateTimeZone $timezone = null)
{
// Workaround not required for PHP 5.3.7 or newer
if (version_compare(PHP_VERSION, '5.3.7', '>=')) {
return parent::__construct($time, $timezone);
}
// Check if using relative constructs
if (!stristr($time, 'last') && !stristr($time, 'first')) {
if ($timezone) {
return parent::__construct($time, $timezone);
} else {
return parent::__construct($time);
}
}
// Use current time with constructor to prevent setting 'first_last_day_of' flag.
// The branching is required for older PHP to prevent DateTime exception of null timezone.
if ($timezone) {
parent::__construct('now', $timezone);
} else {
parent::__construct('now');
}
// Set the timestamp by relying on strtotime and avoiding setting the
// internal 'first_last_day_of' flag of DateTime object.
$this->setTimestamp(
strtotime($time, $this->getTimestamp())
);
return $this;
}
public function modify($modify)
{
// Workaround not required for PHP 5.3.7 or newer
if (version_compare(PHP_VERSION, '5.3.7', '>=')) {
return parent::modify($modify);
}
// Check if using relative constructs
if (!stristr($modify, 'last') && !stristr($modify, 'first')) {
return parent::modify($modify);
}
// Set the timestamp by relying on strtotime and avoiding setting the
// internal 'first_last_day_of' flag of DateTime object.
$parsedTimestamp = strtotime($modify, $this->getTimestamp());
if ($parsedTimestamp === false) {
return false; // something went wrong parsing the date
}
$this->setTimestamp($parsedTimestamp);
return $this;
}
}
class classDateTimeTest {
protected $revertTz = null;
public function setup(){}
public function teardown(){
if($this->revertTz){
date_default_timezone_set($this->revertTz);
$this->revertTz = null;
}
}
protected function setDefaultTz($tz){
if(!$this->revertTz){
$this->revertTz = date_default_timezone_get();
date_default_timezone_set($tz);
}
}
/**
* PHP Bug #62896 Unixtimestamp may take on local times DST flag (this test will only be valid during CEST)
* PHP Bug #62561 DateTime add 'P1D' adds 25 hours
*
* @link https://bugs.php.net/bug.php?id=62896
* @link https://bugs.php.net/bug.php?id=62561
*/
public function testBug62896and62561()
{
$this->setDefaultTz('Europe/Amsterdam');
$tz = new DateTimeZone('Europe/Berlin');
$date = new DateTime('@'.strtotime('2012-08-22 00:00:00 CEST'));
$this->assertEquals(
'2012-08-21 22:00:00 GMT+0000 (offset 0)',
$date->format('Y-m-d H:i:s T').' (offset '.$date->getOffset().")",
'default tz is Amsterdam, date from timestamp, no timezone, after +0 days'
);
$date->modify('+0 days');
$this->assertEquals(
'2012-08-21 22:00:00 GMT+0000 (offset 0)',
$date->format('Y-m-d H:i:s T').' (offset '.$date->getOffset().")",
'default tz is Amsterdam, date from timestamp, no timezone, after +0 days'
);
$date = new DateTime('@'.strtotime('2012-08-22 00:00:00 CEST'));
$date->setTimezone($tz);
$this->assertEquals(
'2012-08-22 00:00:00 CEST (offset 7200)',
$date->format('Y-m-d H:i:s T').' (offset '.$date->getOffset().")",
'default tz is Amsterdam, date from timestamp, with timezone'
);
$date->modify('+0 days');
$this->assertEquals(
'2012-08-22 00:00:00 CEST (offset 7200)',
$date->format('Y-m-d H:i:s T').' (offset '.$date->getOffset().")",
'default tz is Amsterdam, date from timestamp, with timezone, after +0 days'
);
$date = new DateTime('2012-08-22 00:00:00 CEST', $tz);
$this->assertEquals(
'2012-08-22 00:00:00 CEST (offset 7200)',
$date->format('Y-m-d H:i:s T').' (offset '.$date->getOffset().")",
'default tz is Amsterdam, date from a string, with timezone'
);
$date->modify('+0 days');
$date = new DateTime('2012-08-22 00:00:00 CEST', $tz);
$this->assertEquals(
'2012-08-22 00:00:00 CEST (offset 7200)',
$date->format('Y-m-d H:i:s T').' (offset '.$date->getOffset().")",
'default tz is Amsterdam, date from a string, with timezone, after +0 days'
);
}
protected function assertEquals($a, $b, $message = null){
if($a != $b){
throw new \Exception(($message ? $message : "" ) . "\"$a\" != \"$b\"\n");
}
}
}
// run tests
$testClass = new \ReflectionClass(__NAMESPACE__.'\classDateTimeTest');
foreach($testClass->getMethods() as $method){
if(substr($method->getShortName(),0, 4) !== 'test') continue;
try{
$test = new classDateTimeTest();
$test->setup();
$method->invoke($test);
$test->teardown();
}catch(\Exception $e){
echo 'FAIL: '.$method->getShortName().': '.$e->getMessage()."\n";
try{
$test->teardown();
}catch(\Exception $e){}
continue;
}
echo 'PASS: '.$method->getShortName()."\n";
}
Output for git.master, git.master_jit, rfc.property-hooks
Deprecated: Return type of Zend\Stdlib\DateTime::modify($modify) should either be compatible with DateTime::modify(string $modifier): DateTime|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /in/vdORS on line 39
PASS: testBug62896and62561
This tab shows result from various feature-branches currently under review by the php developers. Contact me to have additional branches featured.