處理日期和時間是讓程序員頭疼的問題之一。同時,它們又是軟件開發的基礎,從元數據和事物排序到基於時間的觸發器,以及介於兩者之間的大量應用都離不開它們。
日期和時間也容易出錯。處理不當,它們可能會讓最終用戶和程序員同事都感到困惑。
這是一份關於如何在PHP編程語言中處理日期和時間的快速指南。它旨在作為您最常見需求(如日期格式化和調整)的參考。它很簡單,但很可能涵蓋您80% 的需求。
這項研究得到了Frontend Masters 的支持,Frontend Masters 是CSS-Tricks 的官方學習合作夥伴。
需要前端開發培訓?
Frontend Masters 是學習的最佳場所。他們提供關於所有最重要的前端技術的課程。有興趣成為全棧開發人員嗎?這是您的最佳選擇:
參加課程### 獲取當前日期和時間
需要注意的是,日期和時間可以用三種形式表示:時間戳(即紀元時間)、DateTime 對象和字符串。
首先,獲取當前日期和時間的代碼:
<?php $now = new DateTime(); var_dump($now); // object(DateTime)#1 (3) { // ["date"]=?> // string(26) "2021-10-13 22:25:11.790490" // ["timezone_type"]=> // int(3) // ["timezone"]=> // string(12) "Asia/Jakarta" // }
這提供了一個DateTime 對象,可用於創建日期和時間字符串:
<?php $now = new DateTime(); echo $now-?>format("Ymd"); // 2021-10-13 echo $now->format("Ymd h:i:s A"); // 2021-10-13 10:10:31 PM
您可以直觀地理解Y 代表年份,m 代表月份,d 代表月份中的日期,等等。完整的參數列表可以在PHP 手冊中找到,但我會在此處列出一些最常用的參數以供參考。
DateTime 對象可以轉換為時間戳:
<?php $now = new DateTime(); echo $now-?>getTimestamp(); // 1634139081
但是我們也可以在不構造DateTime 對象的情況下獲取當前時間戳:
<?php echo time(); // 1634139081</pre?><h3>構造特定時間的DateTime 對象</h3> <p>如果我們想為特定時間(例如2011 年7 月14 日)構造一個DateTime 對象,該怎麼辦?我們可以將格式化的日期字符串傳遞給構造函數:</p> <?php $date = new DateTime("2011-07-14"); var_dump($date); // object(DateTime)#1 (3) { // ["date"]=?> // string(26) "2011-07-14 00:00:00.000000" // ["timezone_type"]=> // int(3) // ["timezone"]=> // string(12) "Asia/Jakarta" // } <p>構造函數也接受其他格式:</p> <?php $date = new DateTime("14-07-2011"); var_dump($date); // object(DateTime)#1 (3) { // ["date"]=?> // string(26) "2011-07-14 00:00:00.000000" // ["timezone_type"]=> // int(3) // ["timezone"]=> // string(12) "Asia/Jakarta" // } <p>但是要注意模棱兩可的格式,例如:</p> <?php $date = new DateTime("07/14/2011"); var_dump($date); // object(DateTime)#1 (3) { // ["date"]=?> // string(26) "2011-07-14 00:00:00.000000" // ["timezone_type"]=> // int(3) // ["timezone"]=> // string(12) "Asia/Jakarta" // } <p>您可能認為每個人都應該熟悉美國的日期格式。但並非每個人都熟悉,而且它的解釋可能不同。 PostgreSQL 也不例外。</p> CREATE TABLE IF NOT EXISTS public.datetime_demo ( created_at date ); insert into datetime_demo (created_at) values ('07/12/2011'); select created_at from datetime_demo; /* 2011-12-07 */ <p>您可能認為這將返回2011 年7 月12 日,但它返回的是2011 年12 月7 日。更好的方法是使用顯式格式:</p> <?php $date = DateTime::createFromFormat('m/d/y', "10/08/21"); var_dump($date); //object(DateTime)#2 (3) { // ["date"]=?> // string(26) "2021-10-08 16:00:47.000000" // ["timezone_type"]=> // int(3) // ["timezone"]=> // string(12) "Asia/Jakarta" //} <p>如果我們想從時間戳構造一個DateTime 對象,該怎麼辦?</p> <?php $date = new DateTime(); $date-?>setTimestamp(1634142890); var_dump($date); //object(DateTime)#1 (3) { // ["date"]=> // string(26) "2021-10-13 23:34:50.000000" // ["timezone_type"]=> // int(3) // ["timezone"]=> // string(12) "Asia/Jakarta" // } <p>如果我們想將時間戳對象轉換為格式化的日期字符串,則不必創建DateTime 對象:</p> <?php echo date("Ymd h:i A", time()); // 2021-10-14 04:10 PM</pre?><h3>時區</h3> <p>我們可以創建一個包含時區信息的DateTime 對象,例如,如果我們處理的是太平洋標準時間、東部夏令時間等。</p> <?php $timezone = new DateTimeZone("America/New_York"); $date = new DateTime("2021-10-13 05:00", $timezone); var_dump($date); // object(DateTime)#1 (3) { // ["date"]=?> // string(26) "2021-10-13 05:00:00.000000" // ["timezone_type"]=> // int(3) // ["timezone"]=> // string(16) "America/New_York" // } // 例如,東部夏令時間:紐約$date = new DateTime("2021-10-13 05:00 EDT"); var_dump($date); // object(DateTime)#2 (3) { // ["date"]=> // string(26) "2021-10-13 05:00:00.000000" // ["timezone_type"]=> // int(2) // ["timezone"]=> // string(3) "EDT" // } $date = new DateTime("2021-10-13 05:00 -04:00"); var_dump($date); // object(DateTime)#1 (3) { // ["date"]=> // string(26) "2021-10-13 05:00:00.000000" // ["timezone_type"]=> // int(1) // ["timezone"]=> // string(6) "-04:00" // } <p>有三種方法可以創建包含時區信息的DateTime 對象。 timezone_type 為每種方法接受不同的值。</p> <p>但是,假設我們想將以紐約時區顯示的日期和時間轉換為以雅加達時區顯示,該怎麼辦?</p> <?php $newYorkTimeZone = new DateTimeZone("America/New_York"); $date = new DateTime("2021-11-11 05:00", $newYorkTimeZone); echo $date-?>format("Ymd h:i A"); // 2021-11-11 05:00 AM $jakartaTimeZone = new DateTimeZone("Asia/Jakarta"); $date->setTimeZone($jakartaTimeZone); echo $date->format("Ymd h:i A"); // 2021-11-11 05:00 PM <p>當紐約是凌晨5:00 時,同一天的雅加達是下午5:00。2021 年11 月11 日,雅加達比紐約快12 小時。但一個月前,雅加達只比紐約快11 小時,如下所示:</p> <?php $newYorkTimeZone = new DateTimeZone("America/New_York"); $date = new DateTime("2021-10-11 05:00", $newYorkTimeZone); echo $date-?>format("Ymd h:i A"); // 2021-10-11 05:00 AM $jakartaTimeZone = new DateTimeZone("Asia/Jakarta"); $date->setTimeZone($jakartaTimeZone); echo $date->format("Ymd h:i A"); // 2021-10-11 04:00 PM <p>PHP 會自動處理夏令時。</p> <h3>本地化</h3> <p>這是在美國顯示日期和時間的常用方法:</p> <?php $now = new DateTime(); echo $now-?>format("m/d/Y h:i A"); // 10/14/2021 03:00 PM <p>但是法國的某個人可能更喜歡與其地區更常見的格式。他們可能會抱怨說“這太可怕了”。首先,除了美國之外,沒有人將月份放在日期之前。其次,法國不使用AM 或PM——他們像軍方一樣使用24 小時制(例如14:00 而不是下午2:00)。這就是讓法國當地人滿意的做法。</p> <?php $now = new DateTime(); echo $now-?>format("d/m/YH:i"); // 14/10/2021 15:00 <p>但這需要深入了解特定國家或地區。相反,我們可以對日期進行本地化。要對日期進行本地化,我們需要安裝PHP 的國際化支持。在Ubuntu 中,我們可以執行此步驟:</p> $ sudo apt-get install php-intl <p>要以法語顯示日期和時間,我們可以使用IntlDateFormatter:</p> $locale = "fr_FR.UTF-8"; $formatter = new IntlDateFormatter($locale, IntlDateFormatter::FULL, IntlDateFormatter::SHORT, "Asia/Singapore"); $date = new DateTime("2020-10-10 00:00 UTC"); echo $formatter->format($date); // samedi 10 octobre 2020 à 08:00 <p>您將法語語言環境作為IntlDateFormatter 的第一個參數傳遞。<br>第二個參數是日期的格式。第三個參數是時間的格式。顯示日期和時間的時區位於第四個參數中。</p> <p>除了IntlDateFormatter::FULL 和IntlDateFormatter::SHORT 之外,其他常用的格式還有IntlDateFormatter::NONE、IntlDateFormatter::LONG<br>和IntlDateFormatter::MEDIUM。</p> <p>如果您對時間或第三個參數使用IntlDateFormatter::NONE,則表示您不包含格式中的時間:</p> $locale = "fr_FR.UTF-8"; $formatter = new IntlDateFormatter($locale, IntlDateFormatter::LONG, IntlDateFormatter::NONE, "Asia/Singapore"); $date = new DateTime("2020-10-10 00:00 UTC"); echo $formatter->format($date); // 10 octobre 2020 <h3>時間旅行</h3> <p>讓我們進行時間旅行,回到過去和未來。首先,讓我們了解DateInterval:</p> <?php $interval = new DateInterval("P4M1W2DT2H5M"); // P 4M 1W 2D T 2H 5M // // P = 週期間隔(年、月、週、日) // 4M = 4 個月// 1W = 1 週// 2D = 2 天// // T = 時間間隔(小時、分鐘、秒) // 2H = 2 小時// 5M = 5 分鐘</pre?><p>P 和T 用於分隔週期間隔和時間間隔。以下是我們如何前往未來的方法:</p> <?php $date = new DateTime("2021-10-14"); $interval = new DateInterval("P2D"); // 2 天$futureDate = $date-?>add($interval); echo $futureDate->format("Ymd"); // 2021-10-16 <p>以下是我們如何回到過去的方法:</p> <?php $date = new DateTime("2021-10-14 10:00"); $interval = new DateInterval("PT6H"); // 6 小時$pastDate = $date-?>sub($interval); echo $pastDate->format("Ymd H:i"); // 2021-10-14 04:00 <p>如果我們想使用星期幾的名稱進行時間旅行,我們可以結合使用strtotime() 函數和DateTime 對象的setTimestamp() 方法:</p> <?php $nextTuesday = strtotime("next tuesday"); $date = new DateTime("2021-10-14"); $date-?>setTimestamp($nextTuesday); echo $date->format("Ymd"); // 2021-10-19 <p>請參閱PHP 文檔中strtotime() 參數的完整列表。</p> <h3>定期發生的日期和時間</h3> <p>日曆應用程序中的一項常見功能是設置重複提醒,例如每兩天或每週一次。我們可以使用DatePeriod 來表示一段時間:</p> <?php $start = new DateTime("2021-10-01"); $end = new DateTime("2021-11-01"); $interval = new DateInterval("P1W"); // 1 週$range = new DatePeriod($start, $interval, $end); // 從2021 年10 月1 日開始(包含),每1 週跳過一次// 直到2021 年11 月1 日(不包含) foreach ($range as $date) { echo $date-?>format("Ymd") . "n"; } // 2022-10-01 // 2022-10-08 // 2022-10-15 // 2022-10-22 // 2022-10-29 <h3>多少天前?</h3> <p>您知道像Twitter 這樣的服務會顯示某人X 分鐘/小時/天/等等之前發布的內容嗎?我們可以通過計算當前時間和該操作發生時間之間經過的時間來做到這一點。</p> <?php $date = new DateTime("2022-10-30"); $date2 = new DateTime("2022-10-25"); $date3 = new DateTime("2022-10-10"); $date4 = new DateTime("2022-03-30"); $date5 = new DateTime("2020-03-30"); function get_period_ago($endDate, $startDate) { $dateInterval = $endDate-?>diff($startDate); if ($dateInterval->invert==1) { if ($dateInterval->y > 0) { return $dateInterval->y . " years agon"; } if ($dateInterval->m > 0) { return $dateInterval->m . " months agon"; } if ($dateInterval->d > 7) { return (int)($dateInterval->d / 7) . " weeks agon"; } if ($dateInterval->d > 0) { return $dateInterval->d . " days agon"; } } } echo get_period_ago($date, $date2); // 5 days ago echo get_period_ago($date, $date3); // 2 weeks ago echo get_period_ago($date, $date4); // 7 months ago echo get_period_ago($date, $date5); // 2 years ago <p>從diff() 方法獲取DateInterval 對像後,請確保通過檢查invert 屬性來確保$startDate 變量在過去。然後檢查y、m 和d 屬性。</p> <p>可以在此處PHP 文檔中找到DateInterval 對象屬性的完整列表。</p> <h3>接下來的步驟?</h3> <p>現在您已經掌握了一些處理日期和時間時常用的PHP 代碼片段。需要獲取當前日期和時間嗎?也許您需要以某種方式格式化日期,或者包含本地時區,或者比較日期。所有這些都在這裡!</p> <p>當然,我們還沒有討論更多關於日期和時間的方法和函數——例如與日曆相關的函數等等。請務必隨時查看PHP 手冊的日期和時間部分,以獲取更多用例和示例。</p>
以上是PHP日期和時間食譜的詳細內容。更多資訊請關注PHP中文網其他相關文章!