1. 程式人生 > >在PHP中處理日期

在PHP中處理日期

必須 class 記得 text php 假設 斜杠 7月 並且

前言

有許多話題論壇又來了,話題很多人常常有困難。 其中一個問題是如何處理日期,將其轉換成不同的格式,時區問題,等等。本教程將試圖解決的許多常見問題與日期和時間相關的問題。

在數據庫中存儲日期和時間

包括如何在PHP中處理日期之前,我想談一下應該如何日期存儲在一個數據庫中。 具體我要談談MySQL。因為這就是我最的經驗。 也有其他DBMS設施來處理日期和時間信息,所以你可以查看手冊。

許多人“發明”自己的方式在數據庫中存儲日期,這不可避免地給了他們一些麻煩。 例如他們可能有一個VARCHAR字段類型和存儲日期以DD / MM / YYYY格式。 這是錯誤的方法。

有許多不同的方法可以將日期正確地存儲在一個數據庫中。 一種方法是整數字段,存儲一個Unix時間戳。 我不喜歡這種方法。 它讓你無法使用MySQL的日期和時間函數,並且有潛在的問題Y2K38問題。

MySQL數據類型稱為時間戳。 這將顯示的日期和時間ISO 8601格式,即從最重要的部分(年)最重要的部分(第二)。 一個例子可能是2009-08-18 9:17:21。 額外的格式輸入的時候,其實沒有必要,所以2009081891721將是一樣的。

還有一個數據類型稱為DATETIME。 第一次看它時,它似乎相同的時間戳,但事實並非如此。 首先,時間戳Y2K38仍有問題的事情,所以它只能存儲日期,可以用一個32位無符號整數表示從Unix紀元(1970-01-01就是)。 這給了一個上限2038-01-19 03:14:07。 DATETIME沒有這個問題; 它可以存儲日期從1000-01-01到9999-12-31。 最後,有一些數據類型稱為日期和時間。 這些都是如果你只需要日期或時間只有一部分。

我的建議是使用DATETIME、日期或時間取決於您的需要。 事實上,有一年的類型。 使用MySQL的內置數據類型存儲日期和時間允許您使用它日期和時間函數。

我不會使用數據庫在本教程的其余部分。 示例假設您已經有一些字符串包含一些日期。

時區

這是一個非常常見的問題。 當使用date()函數在PHP中使用服務器時間總是生成日期和時間戳。 除非你是在一個不同的時區比你的服務器,這不是一個問題。 我有一個VPS(虛擬專用服務器)在英國,但我住在丹麥。 這是一個小時的時差。 如何獲得PHP顯示正確的時間給我嗎?

因為我是服務器管理員,我可以改變服務器的時鐘(這是我所做的)。 大多數人不能這樣做,所以我們必須解決這個問題的一些替代方案。

如果你有訪問php。 ini(或者可以改變它的指示使用Apache . htaccess文件)可以改變date.timezone指令(實際上,這需要設置的東西如果你不希望錯誤從PHP)。 否則你可以使用作用是()函數。 手冊有有效的時區列表您可以使用這兩個東西。 因為我在丹麥,我會選擇歐洲/哥本哈根。

讓我們試試:

回聲日期(H:我:年代”);

我的電腦的當地時間是09:34:08,這也是輸出。 現在我們將試圖改變時區:

作用是(“美國/ New_York”);
回聲日期(H:我:年代”);

我們會得到03:34:08。 所以它似乎工作(多麽幸運!)。 這是一個非常好的方法。

如果我們需要多個日期不同的時區,但相同頁面? 這非常簡單。 考慮下面的例子:

作用是(“歐洲/哥本哈根”);
回聲在哥本哈根召開的時間是: 。日期(H:我:年代”) 。PHP_EOL;

作用是(“美國/ New_York”);
回聲”在紐約的時間是: 。日期(H:我:年代”) 。PHP_EOL;

作用是(“歐洲/莫斯科”);
回聲在莫斯科的時間是: 。日期(H:我:年代”) 。PHP_EOL;

將目前的輸出是:

在哥本哈根召開的時間是:09:45:56
在紐約的時間是:03:45:56
在莫斯科的時間是:11:45:56

如果你有用戶從多個時區? 還簡單! 問他們什麽是他們的時區,並相應地設置它。 這個函數timezone_identifiers_list()給你一個數組的所有時區標識符,所以你可以用它來生成一個下拉列表中選擇。 你也可以嘗試確定,拍攝地但這超出了本教程的範圍。

最後,PHP函數函數(),總是在格林尼治時間格式的日期。 如果你知道抵消在幾秒鐘內你可以做:

函數的(H:我:年代”,時間() +抵消美元);

,所以你可能會做的

函數的(H:我:年代”,時間() + 3600年);

一個偏移量的一個小時。 然而,這需要你DST要考慮進去。 並非所有國家遵守DST,一些不同於其他人。 我的建議是使用PHP的內置支持時區。

從一種格式轉換到另一個地方

“我有一個約會在DD / MM / YYYY但是;我需要它。 救命!”

我們如何幫助這個人嗎? 好吧,讓我們分析這個問題。 每個日期由三部分組成:一天,月,年。 所以,我們需要做的是重新排序,使用連字符而不是斜杠。 我們有幾個方式可以做到這一點。 讓我們先試著分裂。 我們有一個函數調用爆炸()的。

oldDate美元= “18/08/2009”; / / DD / MM / YYYY

美元的部分=爆炸(‘ / ‘,oldDate美元);

/ * *
*現在我們有:
*部分美元[0]:一天
*部分美元[1]:
*部分美元[2]:
*我們也可以做:
*列表(日,月,美元美元)=爆炸(“/”,oldDate美元);
* /

newDate美元= “{ $部分[1]} - { $部分[0]} { $部分[2]}”; / /;

echo $ newDate; / / 08-18-2009

這似乎很好工作。 我們還可以使用正則表達式。 這基本上是一個一行程序:

oldDate美元= “18/08/2009”;
newDate美元=preg_replace(“# ^(\ d { 2 })/(\ d { 2 })/(\ d { 4 })$ #”, ‘ $ 2 - $ 1 - $ 3 ‘,oldDate美元);

我不打算解釋正則表達式在本教程中。 你可以看看這個正則表達式教程的。

任何其他方法嗎? 是的,有! 因為它通常是編程,有很多方法可以做到一件事。 假設我們已經分手日期在三個變量美元一天,美元的月和美元一年我們可以用一個函數調用mktime()生成一個Unix時間戳,然後使用日期()格式它以這種方式:

美元的時間戳=mktime(0, 0, 0,美元的月,美元一天,美元一年);
回聲日期(“m-d-Y”,美元的時間戳);

另一種方法是使用strtotime()一個格式化的字符串轉換成一個Unix時間戳。 除了strtotime()不承認DD / MM / YYYY作為一個有效的日期格式,返回false。 也有模棱兩可的問題。 考慮到字符串07-08-2009。 是8月7日還是7月8日? 它將是前者。

日期確認

如果你把一個日期作為輸入(例如生日),這將是非常有用的知道它實際上是一個有效的日期。 有兩個條件必須滿足一個日期之前可以認為是有效的:

  1. 它必須符合特定格式(例如我們可能只希望YYYY-MM-DD)。

  2. 日期必須實際上存在(2009-02-29不存在,但2008-02-29)。

第一個條件是相當簡單的,我們可以使用正則表達式。 第二個是稍微復雜一些。 我們將不得不考慮一個月的長度。 也許這是一個閏年,也許它不是嗎? 幸運的是,我們不必擔心; PHP有一個函數調用checkdate(),嗯…… 檢查日期。 所以,正則表達式和checkdate()是我們所需要的。 一個小例子:

< ?php
如果 ($ _SERVER(“REQUEST_METHOD”] = = “職位” &&收取($ _POST(“日期”))) {
        如果 (preg_match(“# ^(\ d { 4 })-(\ d { 2 })(\ d { 2 })$ #”,$ _POST(“日期”),$匹配) &&checkdate($匹配(2),$匹配(3),$匹配(1))) {
回聲‘ < p > <強>有效日期< / >強壯! < / p > ";
        }
        其他的 {
回聲‘ < p > <強>無效日期< / >強壯! < / p > ";
        }
        
回聲“人力資源> <”;
}
? >

<表單動作= "< ?php echo $ _SERVER(“PHP_SELF”] ? >”方法= " post " >
        <標簽 為=“日期”>輸入一個ISO 8601日期:< /標簽>
< input type = " text " name = "日期" id =“日期”< ?php如果 (!空($ _POST(“日期”])): ? >值= "< ?php echo htmlentities($ _POST(“日期”]) ? >”< ?php endif? >>
        <按鈕 類型=“提交”>檢查的有效性< /按鈕>
< /形式>

這個例子應該是相當簡單的。 首先我們檢查的格式字符串使用preg_match(),我們也提取月,日和年反向引用。 preg_match()返回true,如果字符串是否與模式匹配。 因為邏輯,從左到右的關聯,preg_match()是評價第一,checkdate()僅僅是評估如果第一個操作數是正確的(如果左操作數是假的,和表達不可能返回true,所以評估正確的操作數是多余的,因此它不是的原因)。

如果你有了單獨的字段日、月和年更簡單,我們可以跳過檢查格式。

您可能設置附加條件必須滿足在考慮一個日期之前有效。 你可能會問約會間隔意味著第一個必須比過去早。 你可能只希望日期在過去或未來,或者他們可能要在一個特定的預設時間間隔。 最簡單的方法是將日期轉換為Unix時間戳。 從在此基本的整數的比較。 我把它作為練習。 一個更安全的賭註(記得Y2K38)可能使用DateTime::diff()

在PHP中處理日期