首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 獲取服務器時間解決 8 小時時差:date_default_timezone_set 最佳實踐

     編輯:PHP 相關知識

問題本質

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);
}

進階:DateTimeImmutable 物件導向風格(推薦現代項目)

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.inidate.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 環境變量、數據庫會話時區,構建全棧時區一致性體系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved