在任何編程語言中處理日期和時間通常是一項簡單瑣碎的任務,直到需要支持時區。幸運的是,PHP擁有一套強大的日期/時間工具,可以幫助您處理各種時間相關問題:Unix時間戳、格式化日期以供人類閱讀、顯示帶有時區的日期、計算現在到下個月第二個星期二之間的時間差等等。本文將介紹PHP的時間函數(time()
、mktime()
和date()
)及其面向對像對應項的基礎知識,然後了解MySQL日期,並向您展示如何使它們與PHP完美配合。
主要收穫
- 利用PHP強大的日期和時間函數,如
time()
、mktime()
和date()
,有效處理Unix時間戳和格式化日期。 - 利用PHP的
DateTime
和DateTimeZone
對象進行面向對象的日期和時間操作,包括處理不同的時區。 - 將日期存儲在MySQL中作為Unix時間戳,以保持不同時區之間的一致性,並利用PHP的日期/時間函數進行轉換和格式化。
- 將服務器的默認時區設置為PHP配置中的UTC,以簡化日期和時間管理並確保應用程序的一致性。
PHP日期和時間函數
本文的大部分內容將使用Unix時間,也稱為POSIX時間或紀元時間。時間表示為自1970年1月1日午夜UTC以來經過的秒數。如果您對Unix時間的完整歷史感興趣,請查看維基百科上的Unix時間文章。 UTC(協調世界時),也稱為GMT,有時也稱為Zulu時間,是0度經線的時間。世界上所有其他時區都表示為相對於此時間的正或負偏移量。使用UTC和Unix時間處理時間,在需要處理時區時會讓您的生活更輕鬆。稍後我會詳細介紹這一點,但現在讓我們忽略時區問題,並查看一些時間函數。
獲取當前Unix時間
time()
不接受任何參數,並返回自Unix紀元以來的秒數。為了說明這一點,我將使用PHP交互式CLI shell。
sean@beerhaus:~$ php -a php > print time(); 1324402770
如果您需要Unix時間的數組表示,請使用getdate()
函數。它接受一個可選的Unix時間戳參數,但如果沒有提供,則默認為time()
的值。
php > $unixTime = time(); php > print_r(getdate($unixTime)); Array ( [seconds] => 48 [minutes] => 54 [hours] => 12 [mday] => 20 [wday] => 2 [mon] => 12 [year] => 2011 [yday] => 353 [weekday] => Tuesday [month] => December [0] => 1324403688 )
格式化Unix時間
Unix時間可以輕鬆格式化為人類希望閱讀的任何字符串。 date()
用於將Unix時間戳格式化為人類可讀的字符串,並接受一個格式化參數和一個可選的時間參數。如果沒有提供可選的時間戳,則使用time()
的值。
sean@beerhaus:~$ php -a php > print time(); 1324402770
“r”格式化字符串返回由RFC 2822指定的格式化時間。當然,您可以使用其他說明符來定義您自己的自定義格式。
php > $unixTime = time(); php > print_r(getdate($unixTime)); Array ( [seconds] => 48 [minutes] => 54 [hours] => 12 [mday] => 20 [wday] => 2 [mon] => 12 [year] => 2011 [yday] => 353 [weekday] => Tuesday [month] => December [0] => 1324403688 )
有關可接受的格式化字符的完整列表,請參閱PHP文檔中date()
的頁面。但是,當與mktime()
和strtotime()
函數結合使用時,該函數變得更有用,正如您將在接下來的示例中看到的。
根據給定時間創建Unix時間
mktime()
用於根據與日期的每個部分相對應的值列表(秒、分、小時、年等)創建Unix時間戳。它接受許多整數參數,以以下順序設置日期的每個部分:
php > print date("r", $unixTime); Tue, 20 Dec 2011 12:54:48 -0500
如果啟用了夏令時,則將isDST
設置為1;如果沒有啟用,則設置為0;如果未知,則設置為-1(默認值)。
php > print date("m/d/y h:i:s a", $unixTime); 12/20/11 12:54:48 pm php > print date("m/d/y h:i:s a"); 12/20/11 01:12:11 pm php > print date("jS of F Y", $unixTime); 20th of December 2011
您可以看到,在處理使用用戶自定義日期範圍的數據庫查詢時,mktime()
非常有用。例如,如果您在MySQL中將時間戳存儲為整數(Unix時間)(預示著任何人嗎?),則很容易設置一個常見的年至今查詢範圍。
<code>mktime(hour, minute, second, month, day, year, isDST)</code>
將英文日期解析為Unix時間
幾乎神奇的函數strtotime()
將日期/時間格式的字符串作為其第一個參數,以及用作轉換基礎的Unix時間戳。請參閱文檔以了解可接受的日期格式。
php > print date("r", mktime(12, 0, 0, 1, 20, 1987)); Tue, 20 Jan 1987 12:00:00 -0500 php > print date("r", mktime(0, 0, 0, date("n"), date("j"), date("Y"))); Tue, 20 Dec 2011 00:00:00 -0500 php > print date("r", mktime(23, 59, 59, date("n"), date("j"), date("Y"))); Tue, 20 Dec 2011 23:59:59 -0500
PHP的DateTime和DateTimeZone對象
PHP的DateTime
對像是處理日期和時區的面向對象方法。構造方法接受時間的字符串表示,非常類似於上面的strtotime()
,有些人可能會覺得這更容易使用。如果沒有提供參數,則默認值為“now”。
<?php $startTime = mktime(0, 0, 0, 1, 1, date("y")); $endTime = mktime(0, 0, 0, date("m"), date("d"), date("y"));
DateTime
的format()
方法與上面的date()
函數的工作方式相同,並接受所有相同的格式化字符。 DateTime
對像還帶有一些有用的常量,可以將其饋送到format()
方法。
php > print strtotime("now"); 1324407707 php > print date("r", strtotime("now")); Tue, 20 Dec 2011 14:01:51 -0500 php > print strtotime("+1 week"); 1325012569 php > print date("r", strtotime("+1 week")); Tue, 27 Dec 2011 14:03:03 -0500 php > print date("r", strtotime("next month")); Fri, 20 Jan 2012 14:04:20 -0500 php > print date("r", strtotime("next month", mktime(0, 0, 0))); Fri, 20 Jan 2012 00:00:00 -0500 php > print date("r", strtotime("next month", mktime(0, 0, 0, 1, 31))); Thu, 03 Mar 2011 00:00:00 -0500
可以在DateTime
文檔頁面上找到完整的常量列表。由於我們很快就會處理時區,讓我們為PHP提供一個默認時區。在您的php.ini配置文件(我有一個用於CLI,一個用於Apache)中,找到如下所示的部分:
php > $dt = new DateTime("now"); php > print $dt->format("r"); Tue, 20 Dec 2011 16:28:32 -0500 php > $dt = new DateTime("December 31 1999 12:12:12 EST"); php > print $dt->format("r"); Fri, 31 Dec 1999 12:12:12 -0500
當沒有為date.timezone
賦予值時,PHP將盡力確定在服務器上設置的系統時區。您可以使用date_default_timezone_get()
檢查PHP正在使用哪個值。
sean@beerhaus:~$ php -a php > print time(); 1324402770
讓我們將服務器的時區設置為UTC時間(date.timezone = UTC
)並保存配置文件。您必須重新啟動Apache或CLI shell才能查看更改。 PHP DateTime
對象包括一個內部DateTimeZone
類實例來跟踪時區。當您創建DateTime
的新實例時,內部DateTimeZone
應設置為在php.ini中提供的默認值。
php > $unixTime = time(); php > print_r(getdate($unixTime)); Array ( [seconds] => 48 [minutes] => 54 [hours] => 12 [mday] => 20 [wday] => 2 [mon] => 12 [year] => 2011 [yday] => 353 [weekday] => Tuesday [month] => December [0] => 1324403688 )
可以在時區文檔頁面上找到可接受的時區名稱的完整列表。您現在可以看到當兩個DateTime
對像被賦予不同的時區時,時間差異。例如,這是一個將UTC轉換為America/New_York(EST)時間的示例。
php > print date("r", $unixTime); Tue, 20 Dec 2011 12:54:48 -0500
請注意12月份的-0500偏移量。如果您將時間值更改為夏季日期,例如7月1日,您會發現它知道夏令時(EDT)。
php > print date("m/d/y h:i:s a", $unixTime); 12/20/11 12:54:48 pm php > print date("m/d/y h:i:s a"); 12/20/11 01:12:11 pm php > print date("jS of F Y", $unixTime); 20th of December 2011
將日期與MySQL和PHP一起使用
如果您在任何級別使用過MySQL,您可能已經註意到開箱即用的DATETIME類型。它看起來和聞起來像一個日期,如果您說它是一個日期,那麼您是對的。但是,一旦您將其從MySQL中SELECT到PHP中,您實際上擁有的只是一個看起來像日期的字符串。它沒有時區意識,並且在人類需要查看它之前就已經格式化好供人類使用了。 是的,我知道MySQL有很多日期格式化函數,但我們也已經在使用PHP了,正如您所看到的,PHP在處理日期格式方面非常出色。為什麼我們還要從數據庫中直接格式化它呢?我們可能需要應用一些不同的轉換和格式。最好只在人類即將看到日期時才格式化日期。
<code>mktime(hour, minute, second, month, day, year, isDST)</code>
運行這個簡單的腳本,您可以看到您從DATETIME字段獲得的只是一個格式化的字符串,沒有時區信息。
php > print date("r", mktime(12, 0, 0, 1, 20, 1987)); Tue, 20 Jan 1987 12:00:00 -0500 php > print date("r", mktime(0, 0, 0, date("n"), date("j"), date("Y"))); Tue, 20 Dec 2011 00:00:00 -0500 php > print date("r", mktime(23, 59, 59, date("n"), date("j"), date("Y"))); Tue, 20 Dec 2011 23:59:59 -0500
DATETIME值是運行MySQL的服務器的本地時間,無論該服務器的時區是什麼。如果您所做的所有事情都只涉及一個時區中的一個服務器,那麼DATETIME可能適合您的大部分需求,而且我非常羨慕您。那麼,如何使用PHP和MySQL處理日期和時區呢?將日期存儲為Unix時間戳。您已經知道Unix時間是自1970年1月1日UTC以來的秒數,因此這為您提供了一個恆定的時區,並且您可能已經註意到PHP的許多日期/時間函數都是基於Unix時間戳的。在使用MySQL時,我通常創建將日期存儲為INTEGER UNSIGNED的表列。插入日期時,您可以使用PHP的time()
或MySQL的UNIX_TIMESTAMP()
。
<?php $startTime = mktime(0, 0, 0, 1, 1, date("y")); $endTime = mktime(0, 0, 0, date("m"), date("d"), date("y"));
如果您希望MySQL格式化日期,您可以這樣做。但是時間將位於運行MySQL的服務器的時區中,我建議您在到達Web應用程序的模板/視圖級別並準備好讓人眼看到它之前,不要進行任何類型的格式化。
sean@beerhaus:~$ php -a php > print time(); 1324402770
在任何跨越時區的應用程序中,您通常都會有一個表來跟踪用戶的自定義時區設置,然後將其讀入$_SESSION
值。假設您有一個如下所示的會話條目:
php > $unixTime = time(); php > print_r(getdate($unixTime)); Array ( [seconds] => 48 [minutes] => 54 [hours] => 12 [mday] => 20 [wday] => 2 [mon] => 12 [year] => 2011 [yday] => 353 [weekday] => Tuesday [month] => December [0] => 1324403688 )
您可以輕鬆地將存儲的Unix時間(以UTC為單位)轉換為特定用戶的時區中的任何日期。
php > print date("r", $unixTime); Tue, 20 Dec 2011 12:54:48 -0500
這將導致日期“Mon, 16 Jan 2012 12:03:49 -0600”。 -0600告訴您它比UTC落後6小時,UTC的偏移量為0。如果我們將時區設置為America/Los_Angeles,則生成的日期將是:
php > print date("m/d/y h:i:s a", $unixTime); 12/20/11 12:54:48 pm php > print date("m/d/y h:i:s a"); 12/20/11 01:12:11 pm php > print date("jS of F Y", $unixTime); 20th of December 2011
而America/New_York將產生:
<code>mktime(hour, minute, second, month, day, year, isDST)</code>
總結
處理日期和時區是許多程序員日常生活中的一部分,但是當您可以使用PHP強大且易於使用的日期庫時,無需擔心。您已經了解瞭如何獲取Unix時間戳、如何將日期格式化為任何可以想像的格式、如何將日期的英文表示解析為時間戳、如何將一段時間添加到時間戳以及如何在時區之間進行轉換。如果本文有兩個主要要點,那就是1)堅持使用Unix時間,以及2)在使用PHP和MySQL時,堅持使用UTC作為所有日期的基礎時區。基於UTC的所有時間的想法不僅適用於PHP和MySQL;它在任何語言中都被認為是最佳實踐。如果您發現自己正在使用其他語言工作,那麼您很有可能會對自己說:“該死的,他們為什麼不能像PHP那樣做?”
圖片來自Yakobchuk Vasyl / Shutterstock
(此處應添加關於在PHP中處理日期和時間的常見問題的FAQ部分,類似於輸入文本中的FAQ部分。 由於篇幅限制,我沒有在此處添加。)
以上是在PHP和MySQL中與日期和時間合作的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Laravel使用其直觀的閃存方法簡化了處理臨時會話數據。這非常適合在您的應用程序中顯示簡短的消息,警報或通知。 默認情況下,數據僅針對後續請求: $請求 -

PHP客戶端URL(curl)擴展是開發人員的強大工具,可以與遠程服務器和REST API無縫交互。通過利用Libcurl(備受尊敬的多協議文件傳輸庫),PHP curl促進了有效的執行

Laravel 提供简洁的 HTTP 响应模拟语法,简化了 HTTP 交互测试。这种方法显著减少了代码冗余,同时使您的测试模拟更直观。 基本实现提供了多种响应类型快捷方式: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

PHP日誌記錄對於監視和調試Web應用程序以及捕獲關鍵事件,錯誤和運行時行為至關重要。它為系統性能提供了寶貴的見解,有助於識別問題並支持更快的故障排除

您是否想為客戶最緊迫的問題提供實時的即時解決方案? 實時聊天使您可以與客戶進行實時對話,並立即解決他們的問題。它允許您為您的自定義提供更快的服務

文章討論了PHP 5.3中介紹的PHP中的晚期靜態結合(LSB),允許靜態方法的運行時間分辨率調用以更靈活的繼承。 LSB的實用應用和潛在的觸摸


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

Atom編輯器mac版下載
最受歡迎的的開源編輯器

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具