date()、time()、strtotime() 等函數依賴 **腳本運行時區**,默認為 UTC。中國標準時間 (CST) = UTC+8,故直接調用會少 8 小時。
<?php
// bootstrap.php / index.php / common.php **第一行業務代碼前**
date_default_timezone_set('Asia/Shanghai'); // 推薦:IANA 時區標識符
// 或 date_default_timezone_set('PRC'); // 別名,同義
// 之後所有日期時間函數自動輸出 CST 時間
echo date('Y-m-d H:i:s'); // 正確
<?php
/**
* 獲取服務器當前日期時間 (CST)
*/
function get_server_datetime(): string {
date_default_timezone_set('Asia/Shanghai');
return date('Y-m-d H:i:s');
}
/**
* 獲取服務器當前日期 (CST)
*/
function get_server_date(): string {
date_default_timezone_set('Asia/Shanghai');
return date('Y-m-d');
}
/**
* 獲取服務器當前時間分量 (CST)
* @return array ['h' => 時, 'i' => 分, 's' => 秒]
*/
function get_server_time_parts(): array {
date_default_timezone_set('Asia/Shanghai');
return [
'h' => (int)date('H'), // 24小時制
'i' => (int)date('i'),
's' => (int)date('s'),
];
}
/**
* 格式化任意時間戳為 CST 日期時間
*/
function format_cst(int $timestamp, string $format = 'Y-m-d H:i:s'): string {
date_default_timezone_set('Asia/Shanghai');
return date($format, $timestamp);
}
final class CstDateTime {
private static DateTimeZone $tz;
public static function init(): void {
self::$tz = new DateTimeZone('Asia/Shanghai');
}
public static function now(): DateTimeImmutable {
return new DateTimeImmutable('now', self::$tz);
}
public static function fromTimestamp(int $ts): DateTimeImmutable {
return (new DateTimeImmutable('@' . $ts))->setTimezone(self::$tz);
}
public static function format(DateTimeInterface $dt, string $fmt = 'Y-m-d H:i:s'): string {
return $dt->setTimezone(self::$tz)->format($fmt);
}
}
// 啟動時調用一次
CstDateTime::init();
// 業務使用
$now = CstDateTime::now();
echo $now->format('Y-m-d H:i:s');
echo CstDateTime::format($now);
| 層面 | 配置 |
|---|---|
| PHP php.ini | date.timezone = Asia/Shanghai |
| Docker 容器 | ENV TZ=Asia/Shanghai 或掛載 /etc/localtime |
| MySQL 會話 | SET time_zone = '+08:00' 或 DSN timezone=+08:00 |
| Redis/Laravel 等框架 | 配置文件 'timezone' => 'Asia/Shanghai' |
| 日誌/監控系統 | 統一 UTC 存儲,展示層按用戶時區轉換 |
date('h:i:s') 是 12 小時制,**存儲/傳輸務必用 24 制 H:i:s**。time()、strtotime())本身**無時區概念**(均為 UTC 秒數),只有格式化輸出才涉及時區。**「腳本入口第一行 date_default_timezone_set('Asia/Shanghai')」是解決 8 小時時差的銀彈**。配合 php.ini 全局設置、Docker 環境變量、數據庫會話時區,構建全棧時區一致性體系。