Fix timezone conversion

This commit is contained in:
bancer 2019-01-25 12:05:44 +01:00
parent 7911bb9052
commit 044e8f24af
2 changed files with 82 additions and 23 deletions

View file

@ -990,7 +990,19 @@ class CakeTimeTest extends CakeTestCase {
$clientDateTime = new DateTime('2019-01-31 10:00:00', $clientTimeZone);
// Convert to UTC.
$actual = CakeTime::fromString($clientDateTime, 'UTC');
$expected = 1548900000; // '2019-01-31 03:00:00' timestamp
$clientDateTime->setTimezone(new DateTimeZone('UTC'));
$expected = $clientDateTime->getTimestamp() + $clientDateTime->getOffset(); // 1548903600
$this->assertEquals($expected, $actual);
$this->_restoreSystemTimezone();
}
public function testFromStringUTCtoCopenhagen() {
date_default_timezone_set('UTC'); // server timezone
$clientTimeZone = new DateTimeZone('UTC');
$clientDateTime = new DateTime('2012-01-01 10:00:00', $clientTimeZone);
$actual = CakeTime::fromString($clientDateTime, 'Europe/Copenhagen');
$clientDateTime->setTimezone(new DateTimeZone('Europe/Copenhagen'));
$expected = $clientDateTime->getTimestamp() + $clientDateTime->getOffset(); // 1325415600
$this->assertEquals($expected, $actual);
$this->_restoreSystemTimezone();
}
@ -1007,6 +1019,25 @@ class CakeTimeTest extends CakeTestCase {
$this->assertEquals($result, $date->format('U'));
}
public function testConvertToBangkok() {
$serverTimeZoneName = 'Europe/Copenhagen';
date_default_timezone_set($serverTimeZoneName);
$serverTimeZone = new DateTimeZone($serverTimeZoneName);
$DateTime = new DateTime('2019-01-31 04:00:00', $serverTimeZone);
$serverTimestamp = $DateTime->getTimestamp() + $DateTime->getOffset(); // 1548907200
$clientTimeZoneName = 'Asia/Bangkok';
$clientTimeZone = new DateTimeZone($clientTimeZoneName);
$DateTime->setTimezone($clientTimeZone);
$expected = $DateTime->getTimestamp() + $DateTime->getOffset(); // 1548928800
$actual = CakeTime::convert($serverTimestamp, $clientTimeZoneName);
$this->assertEquals($expected, $actual);
$this->_restoreSystemTimezone();
}
/**
* test converting time specifiers using a time definition localfe file
*
@ -1096,15 +1127,6 @@ class CakeTimeTest extends CakeTestCase {
$this->assertEquals($expected, $result);
}
public function testConvertTimezoneConversionToUTC() {
date_default_timezone_set('Europe/Copenhagen'); // server timezone
$serverTime = 1548903600; // '2019-01-31 04:00:00' timestamp
$actual = CakeTime::convert($serverTime, 'UTC');
$expected = 1548900000; // '2019-01-31 03:00:00' timestamp
$this->assertEquals($expected, $actual);
$this->_restoreSystemTimezone();
}
/**
* test convert %e on Windows.
*
@ -1173,10 +1195,22 @@ class CakeTimeTest extends CakeTestCase {
$clientDateTime = new DateTime('2019-01-31 10:00:00', $clientTimeZone);
// Convert to UTC.
$actual = CakeTime::i18nFormat($clientDateTime, '%Y-%m-%d %H:%M:%S', false, 'UTC');
$this->assertEquals('2019-01-31 03:00:00', $actual);
$clientDateTime->setTimezone(new DateTimeZone('UTC'));
$expected = $clientDateTime->format('Y-m-d H:i:s');
$this->assertEquals($expected, $actual);
$this->_restoreSystemTimezone();
}
public function testI18nFormatUTCtoCopenhagen() {
date_default_timezone_set('UTC');
$clientTimeZone = new DateTimeZone('UTC');
$clientDateTime = new DateTime('2012-01-01 10:00:00', $clientTimeZone);
$actual = CakeTime::i18nFormat($clientDateTime, '%Y-%m-%d %H:%M', false, 'Europe/Copenhagen');
$clientDateTime->setTimezone(new DateTimeZone('Europe/Copenhagen'));
$expected = $clientDateTime->format('Y-m-d H:i');
$this->assertEquals($expected, $actual);
}
/**
* test new format() syntax which inverts first and second parameters
*
@ -1245,7 +1279,7 @@ class CakeTimeTest extends CakeTestCase {
*
* @return void
*/
public function testCorrectTimezoneConversion() {
public function testCorrectTimezoneConversionAsString() {
date_default_timezone_set('UTC');
$date = '2012-01-01 10:00:00';
$converted = CakeTime::format($date, '%Y-%m-%d %H:%M', '', 'Europe/Copenhagen');
@ -1254,13 +1288,26 @@ class CakeTimeTest extends CakeTestCase {
$this->assertEquals($expected->format('Y-m-d H:i'), $converted);
}
public function testCorrectTimezoneConversionAsObject() {
date_default_timezone_set('UTC');
$clientTimeZone = new DateTimeZone('UTC');
$date = '2012-01-01 10:00:00';
$clientDateTime = new DateTime($date, $clientTimeZone);
$converted = CakeTime::format($clientDateTime, '%Y-%m-%d %H:%M', '', 'Europe/Copenhagen');
$clientDateTime->setTimezone(new DateTimeZone('Europe/Copenhagen'));
$expected = $clientDateTime->format('Y-m-d H:i');
$this->assertEquals($expected, $converted);
}
public function testFormatTimezoneConversionToUTC() {
date_default_timezone_set('Europe/Copenhagen'); // server timezone
$clientTimeZone = new DateTimeZone('Asia/Bangkok');
$clientDateTime = new DateTime('2019-01-31 10:00:00', $clientTimeZone);
// Convert to UTC.
$actual = CakeTime::format($clientDateTime, '%Y-%m-%d %H:%M:%S', false, 'UTC');
$this->assertEquals('2019-01-31 03:00:00', $actual);
$clientDateTime->setTimezone(new DateTimeZone('UTC'));
$expected = $clientDateTime->format('Y-m-d H:i:s');
$this->assertEquals($expected, $actual);
$this->_restoreSystemTimezone();
}

View file

@ -239,9 +239,9 @@ class CakeTime {
/**
* Converts given time (in server's time zone) to user's local time, given his/her timezone.
*
* @param string $serverTime UNIX timestamp
* @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
* @return int UNIX timestamp
* @param integer $serverTime Server's timestamp.
* @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object.
* @return int User's timezone timestamp.
* @link https://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::convert
*/
public static function convert($serverTime, $timezone) {
@ -303,11 +303,11 @@ class CakeTime {
}
/**
* Returns a UNIX timestamp, given either a UNIX timestamp or a valid strtotime() date string.
* Returns a timestamp, given either a UNIX timestamp or a valid strtotime() date string.
*
* @param int|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
* @return string Parsed timestamp
* @return int|false Parsed given timezone timestamp.
* @link https://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::fromString
*/
public static function fromString($dateString, $timezone = null) {
@ -327,7 +327,7 @@ class CakeTime {
) {
$clone = clone $dateString;
$clone->setTimezone(new DateTimeZone(date_default_timezone_get()));
$date = (int)$clone->format('U')/* + $clone->getOffset()*/;
$date = (int)$clone->format('U') + $clone->getOffset();
} elseif ($dateString instanceof DateTime) {
$date = (int)$dateString->format('U');
} else {
@ -1055,17 +1055,29 @@ class CakeTime {
* @link https://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::i18nFormat
*/
public static function i18nFormat($date, $format = null, $default = false, $timezone = null) {
$date = static::fromString($date, $timezone);
if ($date === false && $default !== false) {
$timestamp = static::fromString($date, $timezone);
if ($timestamp === false && $default !== false) {
return $default;
}
if ($date === false) {
if ($timestamp === false) {
return '';
}
if (empty($format)) {
$format = '%x';
}
return static::_strftime(static::convertSpecifiers($format, $date), $date);
$serverTimeZone = date_default_timezone_get();
if (
!empty($timezone) &&
$date instanceof DateTime &&
$date->getTimezone()->getName() != $serverTimeZone
) {
date_default_timezone_set($timezone);
}
$result = static::_strftime(static::convertSpecifiers($format, $timestamp), $timestamp);
if (!empty($serverTimeZone)) {
date_default_timezone_set($serverTimeZone);
}
return $result;
}
/**