mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-04 22:57:40 +08:00
added Formatter::defaultTimeZone to allow non UTC-values in DB
fixes #5683
This commit is contained in:
@ -124,6 +124,9 @@ echo Yii::$app->formatter->asTime('2014-10-06 12:41:00'); // 14:41:00
|
|||||||
echo Yii::$app->formatter->asTime('2014-10-06 14:41:00 CEST'); // 14:41:00
|
echo Yii::$app->formatter->asTime('2014-10-06 14:41:00 CEST'); // 14:41:00
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Since version 2.0.1 it is also possible to configure the time zone that is assumed for timestamps that do not include a time zone
|
||||||
|
identifier like the second example in the code above. You can set [[yii\i18n\Formatter::defaultTimeZone]] to the time zone you use for data storage.
|
||||||
|
|
||||||
> Note: As time zones are subject to rules made by the governments around the world and may change frequently, it is
|
> Note: As time zones are subject to rules made by the governments around the world and may change frequently, it is
|
||||||
> likely that you do not have the latest information in the time zone database installed on your system.
|
> likely that you do not have the latest information in the time zone database installed on your system.
|
||||||
> You may refer to the [ICU manual](http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data)
|
> You may refer to the [ICU manual](http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data)
|
||||||
|
|||||||
@ -43,6 +43,7 @@ Yii Framework 2 Change Log
|
|||||||
- Enh #5600: Allow configuring debug panels in `yii\debug\Module::panels` as panel class name strings (qiangxue)
|
- Enh #5600: Allow configuring debug panels in `yii\debug\Module::panels` as panel class name strings (qiangxue)
|
||||||
- Enh #5613: Added `--overwrite` option to Gii console command to support overwriting all files (motin, qiangxue)
|
- Enh #5613: Added `--overwrite` option to Gii console command to support overwriting all files (motin, qiangxue)
|
||||||
- Enh #5646: Call `yii\base\ErrorHandler::unregister()` instead of `restore_*_handlers` directly (aivus)
|
- Enh #5646: Call `yii\base\ErrorHandler::unregister()` instead of `restore_*_handlers` directly (aivus)
|
||||||
|
- Enh #5683: Added `yii\i18n\Formatter::defaultTimeZone` for specifying the default time zone to use for datetime values stored in the database (cebe)
|
||||||
- Enh #5688: Added optional `$formName` to `Model::loadMultiple()` to support customizing form name directly (qiangxue)
|
- Enh #5688: Added optional `$formName` to `Model::loadMultiple()` to support customizing form name directly (qiangxue)
|
||||||
- Enh #5735: Added `yii\bootstrap\Tabs::renderTabContent` to support manually rendering tab contents (RomeroMsk)
|
- Enh #5735: Added `yii\bootstrap\Tabs::renderTabContent` to support manually rendering tab contents (RomeroMsk)
|
||||||
- Enh #5770: Added more PHP error names for `ErrorException` (mongosoft)
|
- Enh #5770: Added more PHP error names for `ErrorException` (mongosoft)
|
||||||
|
|||||||
@ -64,16 +64,26 @@ class Formatter extends Component
|
|||||||
*/
|
*/
|
||||||
public $locale;
|
public $locale;
|
||||||
/**
|
/**
|
||||||
* @var string the timezone to use for formatting time and date values.
|
* @var string the time zone to use for formatting time and date values.
|
||||||
|
*
|
||||||
* This can be any value that may be passed to [date_default_timezone_set()](http://www.php.net/manual/en/function.date-default-timezone-set.php)
|
* This can be any value that may be passed to [date_default_timezone_set()](http://www.php.net/manual/en/function.date-default-timezone-set.php)
|
||||||
* e.g. `UTC`, `Europe/Berlin` or `America/Chicago`.
|
* e.g. `UTC`, `Europe/Berlin` or `America/Chicago`.
|
||||||
* Refer to the [php manual](http://www.php.net/manual/en/timezones.php) for available timezones.
|
* Refer to the [php manual](http://www.php.net/manual/en/timezones.php) for available time zones.
|
||||||
* If this property is not set, [[\yii\base\Application::timeZone]] will be used.
|
* If this property is not set, [[\yii\base\Application::timeZone]] will be used.
|
||||||
*
|
*
|
||||||
* Note that the input timezone is assumed to be UTC always if no timezone is included in the input date value.
|
* Note that the default time zone for input data is assumed to be UTC by default if no time zone is included in the input date value.
|
||||||
* Make sure to store datetime values in UTC in your database.
|
* If you store your data in a different time zone in the database, you have to adjust [[defaultTimeZone]] accordingly.
|
||||||
*/
|
*/
|
||||||
public $timeZone;
|
public $timeZone;
|
||||||
|
/**
|
||||||
|
* @var string the time zone that is assumed for input values if they do not include a time zone explicitly.
|
||||||
|
*
|
||||||
|
* The value must be a valid time zone identifier, e.g. `UTC`, `Europe/Berlin` or `America/Chicago`.
|
||||||
|
* Please refer to the [php manual](http://www.php.net/manual/en/timezones.php) for available time zones.
|
||||||
|
*
|
||||||
|
* It defaults to `UTC` so you only have to adjust this value if you store datetime values in another time zone in your database.
|
||||||
|
*/
|
||||||
|
public $defaultTimeZone = 'UTC';
|
||||||
/**
|
/**
|
||||||
* @var string the default format string to be used to format a [[asDate()|date]].
|
* @var string the default format string to be used to format a [[asDate()|date]].
|
||||||
* This can be "short", "medium", "long", or "full", which represents a preset format of different lengths.
|
* This can be "short", "medium", "long", or "full", which represents a preset format of different lengths.
|
||||||
@ -402,7 +412,7 @@ class Formatter extends Component
|
|||||||
*
|
*
|
||||||
* - an integer representing a UNIX timestamp
|
* - an integer representing a UNIX timestamp
|
||||||
* - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php).
|
* - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php).
|
||||||
* The timestamp is assumed to be in UTC unless a timezone is explicitly given.
|
* The timestamp is assumed to be in [[defaultTimeZone]] unless a time zone is explicitly given.
|
||||||
* - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object
|
* - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object
|
||||||
*
|
*
|
||||||
* @param string $format the format used to convert the value into a date string.
|
* @param string $format the format used to convert the value into a date string.
|
||||||
@ -434,7 +444,7 @@ class Formatter extends Component
|
|||||||
*
|
*
|
||||||
* - an integer representing a UNIX timestamp
|
* - an integer representing a UNIX timestamp
|
||||||
* - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php).
|
* - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php).
|
||||||
* The timestamp is assumed to be in UTC unless a timezone is explicitly given.
|
* The timestamp is assumed to be in [[defaultTimeZone]] unless a time zone is explicitly given.
|
||||||
* - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object
|
* - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object
|
||||||
*
|
*
|
||||||
* @param string $format the format used to convert the value into a date string.
|
* @param string $format the format used to convert the value into a date string.
|
||||||
@ -466,7 +476,7 @@ class Formatter extends Component
|
|||||||
*
|
*
|
||||||
* - an integer representing a UNIX timestamp
|
* - an integer representing a UNIX timestamp
|
||||||
* - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php).
|
* - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php).
|
||||||
* The timestamp is assumed to be in UTC unless a timezone is explicitly given.
|
* The timestamp is assumed to be in [[defaultTimeZone]] unless a time zone is explicitly given.
|
||||||
* - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object
|
* - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object
|
||||||
*
|
*
|
||||||
* @param string $format the format used to convert the value into a date string.
|
* @param string $format the format used to convert the value into a date string.
|
||||||
@ -507,7 +517,7 @@ class Formatter extends Component
|
|||||||
*
|
*
|
||||||
* - an integer representing a UNIX timestamp
|
* - an integer representing a UNIX timestamp
|
||||||
* - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php).
|
* - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php).
|
||||||
* The timestamp is assumed to be in UTC unless a timezone is explicitly given.
|
* The timestamp is assumed to be in [[defaultTimeZone]] unless a time zone is explicitly given.
|
||||||
* - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object
|
* - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object
|
||||||
*
|
*
|
||||||
* @param string $format the format used to convert the value into a date string.
|
* @param string $format the format used to convert the value into a date string.
|
||||||
@ -562,7 +572,7 @@ class Formatter extends Component
|
|||||||
*
|
*
|
||||||
* - an integer representing a UNIX timestamp
|
* - an integer representing a UNIX timestamp
|
||||||
* - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php).
|
* - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php).
|
||||||
* The timestamp is assumed to be in UTC unless a timezone is explicitly given.
|
* The timestamp is assumed to be in [[defaultTimeZone]] unless a time zone is explicitly given.
|
||||||
* - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object
|
* - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object
|
||||||
*
|
*
|
||||||
* @return DateTime the normalized datetime value
|
* @return DateTime the normalized datetime value
|
||||||
@ -578,18 +588,18 @@ class Formatter extends Component
|
|||||||
$value = 0;
|
$value = 0;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (is_numeric($value)) { // process as unix timestamp
|
if (is_numeric($value)) { // process as unix timestamp, which is always in UTC
|
||||||
if (($timestamp = DateTime::createFromFormat('U', $value, new DateTimeZone('UTC'))) === false) {
|
if (($timestamp = DateTime::createFromFormat('U', $value, new DateTimeZone('UTC'))) === false) {
|
||||||
throw new InvalidParamException("Failed to parse '$value' as a UNIX timestamp.");
|
throw new InvalidParamException("Failed to parse '$value' as a UNIX timestamp.");
|
||||||
}
|
}
|
||||||
return $timestamp;
|
return $timestamp;
|
||||||
} elseif (($timestamp = DateTime::createFromFormat('Y-m-d', $value, new DateTimeZone('UTC'))) !== false) { // try Y-m-d format (support invalid dates like 2012-13-01)
|
} elseif (($timestamp = DateTime::createFromFormat('Y-m-d', $value, new DateTimeZone($this->defaultTimeZone))) !== false) { // try Y-m-d format (support invalid dates like 2012-13-01)
|
||||||
return $timestamp;
|
return $timestamp;
|
||||||
} elseif (($timestamp = DateTime::createFromFormat('Y-m-d H:i:s', $value, new DateTimeZone('UTC'))) !== false) { // try Y-m-d H:i:s format (support invalid dates like 2012-13-01 12:63:12)
|
} elseif (($timestamp = DateTime::createFromFormat('Y-m-d H:i:s', $value, new DateTimeZone($this->defaultTimeZone))) !== false) { // try Y-m-d H:i:s format (support invalid dates like 2012-13-01 12:63:12)
|
||||||
return $timestamp;
|
return $timestamp;
|
||||||
}
|
}
|
||||||
// finally try to create a DateTime object with the value
|
// finally try to create a DateTime object with the value
|
||||||
$timestamp = new DateTime($value, new DateTimeZone('UTC'));
|
$timestamp = new DateTime($value, new DateTimeZone($this->defaultTimeZone));
|
||||||
return $timestamp;
|
return $timestamp;
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
throw new InvalidParamException("'$value' is not a valid date time value: " . $e->getMessage()
|
throw new InvalidParamException("'$value' is not a valid date time value: " . $e->getMessage()
|
||||||
@ -604,7 +614,7 @@ class Formatter extends Component
|
|||||||
*
|
*
|
||||||
* - an integer representing a UNIX timestamp
|
* - an integer representing a UNIX timestamp
|
||||||
* - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php).
|
* - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php).
|
||||||
* The timestamp is assumed to be in UTC unless a timezone is explicitly given.
|
* The timestamp is assumed to be in [[defaultTimeZone]] unless a time zone is explicitly given.
|
||||||
* - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object
|
* - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object
|
||||||
*
|
*
|
||||||
* @return string the formatted result.
|
* @return string the formatted result.
|
||||||
@ -632,7 +642,7 @@ class Formatter extends Component
|
|||||||
*
|
*
|
||||||
* - an integer representing a UNIX timestamp
|
* - an integer representing a UNIX timestamp
|
||||||
* - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php).
|
* - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php).
|
||||||
* The timestamp is assumed to be in UTC unless a timezone is explicitly given.
|
* The timestamp is assumed to be in [[defaultTimeZone]] unless a time zone is explicitly given.
|
||||||
* - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object
|
* - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object
|
||||||
* - a PHP DateInterval object (a positive time interval will refer to the past, a negative one to the future)
|
* - a PHP DateInterval object (a positive time interval will refer to the past, a negative one to the future)
|
||||||
*
|
*
|
||||||
@ -662,16 +672,16 @@ class Formatter extends Component
|
|||||||
return $this->nullDisplay;
|
return $this->nullDisplay;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$timezone = new DateTimeZone($this->timeZone);
|
$timeZone = new DateTimeZone($this->timeZone);
|
||||||
|
|
||||||
if ($referenceTime === null) {
|
if ($referenceTime === null) {
|
||||||
$dateNow = new DateTime('now', $timezone);
|
$dateNow = new DateTime('now', $timeZone);
|
||||||
} else {
|
} else {
|
||||||
$dateNow = $this->normalizeDatetimeValue($referenceTime);
|
$dateNow = $this->normalizeDatetimeValue($referenceTime);
|
||||||
$dateNow->setTimezone($timezone);
|
$dateNow->setTimezone($timeZone);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dateThen = $timestamp->setTimezone($timezone);
|
$dateThen = $timestamp->setTimezone($timeZone);
|
||||||
|
|
||||||
$interval = $dateThen->diff($dateNow);
|
$interval = $dateThen->diff($dateNow);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -582,6 +582,53 @@ class FormatterTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test timezones with input date and time in other timezones
|
||||||
|
*/
|
||||||
|
public function testTimezoneInputNonDefault()
|
||||||
|
{
|
||||||
|
$this->formatter->datetimeFormat = 'yyyy-MM-dd HH:mm:ss';
|
||||||
|
$this->formatter->dateFormat = 'yyyy-MM-dd';
|
||||||
|
$this->formatter->timeFormat = 'HH:mm:ss';
|
||||||
|
|
||||||
|
$this->formatter->timeZone = 'UTC';
|
||||||
|
$this->formatter->defaultTimeZone = 'UTC';
|
||||||
|
$this->assertSame('2014-08-10 12:41:00', $this->formatter->asDatetime('2014-08-10 12:41:00'));
|
||||||
|
$this->assertSame('2014-08-10', $this->formatter->asDate('2014-08-10 12:41:00'));
|
||||||
|
$this->assertSame('12:41:00', $this->formatter->asTime('2014-08-10 12:41:00'));
|
||||||
|
$this->assertSame('1407674460', $this->formatter->asTimestamp('2014-08-10 12:41:00'));
|
||||||
|
|
||||||
|
$this->assertSame('2014-08-10 10:41:00', $this->formatter->asDatetime('2014-08-10 12:41:00 Europe/Berlin'));
|
||||||
|
$this->assertSame('2014-08-10', $this->formatter->asDate('2014-08-10 12:41:00 Europe/Berlin'));
|
||||||
|
$this->assertSame('10:41:00', $this->formatter->asTime('2014-08-10 12:41:00 Europe/Berlin'));
|
||||||
|
$this->assertSame('1407674460', $this->formatter->asTimestamp('2014-08-10 14:41:00 Europe/Berlin'));
|
||||||
|
|
||||||
|
$this->formatter->timeZone = 'Europe/Berlin';
|
||||||
|
$this->formatter->defaultTimeZone = 'Europe/Berlin';
|
||||||
|
$this->assertSame('2014-08-10 12:41:00', $this->formatter->asDatetime('2014-08-10 12:41:00'));
|
||||||
|
$this->assertSame('2014-08-10', $this->formatter->asDate('2014-08-10 12:41:00'));
|
||||||
|
$this->assertSame('12:41:00', $this->formatter->asTime('2014-08-10 12:41:00'));
|
||||||
|
$this->assertSame('1407674460', $this->formatter->asTimestamp('2014-08-10 14:41:00'));
|
||||||
|
|
||||||
|
$this->assertSame('2014-08-10 12:41:00', $this->formatter->asDatetime('2014-08-10 12:41:00 Europe/Berlin'));
|
||||||
|
$this->assertSame('2014-08-10', $this->formatter->asDate('2014-08-10 12:41:00 Europe/Berlin'));
|
||||||
|
$this->assertSame('12:41:00', $this->formatter->asTime('2014-08-10 12:41:00 Europe/Berlin'));
|
||||||
|
$this->assertSame('1407674460', $this->formatter->asTimestamp('2014-08-10 14:41:00 Europe/Berlin'));
|
||||||
|
|
||||||
|
$this->formatter->timeZone = 'UTC';
|
||||||
|
$this->formatter->defaultTimeZone = 'Europe/Berlin';
|
||||||
|
$this->assertSame('2014-08-10 10:41:00', $this->formatter->asDatetime('2014-08-10 12:41:00'));
|
||||||
|
$this->assertSame('2014-08-10', $this->formatter->asDate('2014-08-10 12:41:00'));
|
||||||
|
$this->assertSame('10:41:00', $this->formatter->asTime('2014-08-10 12:41:00'));
|
||||||
|
$this->assertSame('1407674460', $this->formatter->asTimestamp('2014-08-10 14:41:00'));
|
||||||
|
|
||||||
|
$this->assertSame('2014-08-10 12:41:00', $this->formatter->asDatetime('2014-08-10 12:41:00 UTC'));
|
||||||
|
$this->assertSame('2014-08-10', $this->formatter->asDate('2014-08-10 12:41:00 UTC'));
|
||||||
|
$this->assertSame('12:41:00', $this->formatter->asTime('2014-08-10 12:41:00 UTC'));
|
||||||
|
$this->assertSame('1407674460', $this->formatter->asTimestamp('2014-08-10 12:41:00 UTC'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// number format
|
// number format
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user