關於時間PHP處理包遇到的問題
問題描述,最近在寫專案的時候,因為是一個多語言的專案,而且對於本地化時間也做了處理,再加上在宣傳頁面,不同的地方,做了不同格式的展示時間的
處理,最重要一點,這是一個使用laravel開發的專案,安裝一個方便的時間處理包真的是太方便了,而且carbon
還是這麼的強大。後臺的使用者在釋出一個宣傳文章的時候,有時候會使用一個預釋出的功能,那麼前臺在預釋出的時間之後,就會顯示這個宣傳文章,現在的問題就是,比如
我選擇一個早上八點之前的預釋出時間,那麼使用carbon
處理時間之後,這個顯示的時間,會比預釋出的時間晚一天。如果選擇早上八點之後,最後格式話的
時間就是正常的。在配置檔案裡,
app.php
我配置的時區是PRC
,做本地化處理的時候,
//這個地方是根據站點的切換來動態切換
Carbon::setLocale('en');
$time1 = Carbon::parse(strtotime('2020-06-12 06:00:00'))->isoFormat('LL');
var_dump($time1);
$time2 = Carbon::parse(strtotime('2020-06-12 07:00:00'))->isoFormat('LL');
var_dump($time2);
$time3 = Carbon::parse(strtotime('2020-06-12 09:00:00'))->isoFormat('LL');
var_dump($time3);
//June 11, 2020
//June 11, 2020
//June 12, 2020
這個例子得到的處理之後的時間就是晚一天的,它會減去八個小時
如果是我這樣處理就不會有問題
//這個第二個引數就是動態切換的
$carbon = new Carbon('2020-08-06 06:00:00', 'en');
$carbon->isoFormat('LL');
//or
$time1 = Carbon::parse('2020-06-12 06:00:00')->isoFormat('LL');
var_dump($time1);
$time2 = Carbon::parse('2020-06-12 06:00:00')->isoFormat('LL');
var_dump($time2);
$time3 = Carbon::parse('2020-06-12 06:00:00')->isoFormat('LL');
var_dump($time3);
這個列印出來時間就是正常的,問題就是出在是否使用了php的自帶函式strtotime()
。我如果傳一個時間戳過去,這個時候時間的轉換就會出現差錯,如果
傳一個時間戳,就會走到這一步:
public function __construct($time = null, $tz = null)
{
if (is_int($time)) {
$time = "@$time";
}
$originalTz = $tz;
// If the class has a test now set and we are trying to create a now()
// instance then override as required
$isNow = empty($time) || $time === 'now';
if (method_exists(static::class, 'hasTestNow') &&
method_exists(static::class, 'getTestNow') &&
static::hasTestNow() &&
($isNow || static::hasRelativeKeywords($time))
) {
static::mockConstructorParameters($time, $tz);
}
/** @var CarbonTimeZone $timezone */
$timezone = $this->autoDetectTimeZone($tz, $originalTz);
// Work-around for PHP bug https://bugs.php.net/bug.php?id=67127
if (strpos((string) .1, '.') === false) {
$locale = setlocale(LC_NUMERIC, '0');
setlocale(LC_NUMERIC, 'C');
}
parent::__construct($time ?: 'now', $timezone);
if (isset($locale)) {
setlocale(LC_NUMERIC, $locale);
}
static::setLastErrors(parent::getLastErrors());
}
這個__construct
方法會繼承父類的__construct()
,而它在傳遞給父類的時候,會檢測時間戳是否是一個int
型別,如果是就會轉換為字串的型別
這個時候,父類DateTime::__construct
DateTime在處理的時候,再格式話
輸出時間的時候,就會出現時間查。
- 總結,追了一圈才發現不是
carbon
的bug,同時也發現了這個問題,再下次使用時間戳的時候,需要注意,禁忌
本作品採用《CC 協議》,轉載必須註明作者和本文連結
LIYi ---- github地址