2017-05-31 64 views
5

今天我遇到了一些令我困惑的事情,\DateTime::createFromFormat函數的行爲。PHP DateTime :: createFromFormat behaviiur

在我的情況下,我有一個字符串,代表以下格式的日期m/Y (05/2017)。當我想的字符串DateTime對象轉換我遇到了以下問題:

$date = \DateTime::createFromFormat('m/Y', '02/2017');

當我轉儲$date變量,日期屬性裏面'2017-03-03 11:06:36.000000'

但是,如果我添加日期在月份之前$date = \DateTime::createFromFormat('d/m/Y', '01/02/2017');我找回具有正確日期屬性的對象。 (不幸的是我不能改變日期的格式並添加一天,它必須是m/Y)。

我想出的修復方法是將月份的第一天連接到日期字符串,我有$date = '01/'.$dateString;但我寧願不這樣做,因爲它是硬編碼的。

這裏有什麼問題? createFromFormat函數是否缺少如何創建對象的信息?我對此很困惑。感謝大家的幫助!

+0

這只是創建對象,後續代碼var_dump $日期 - >格式()(格式是一樣的日期,所以年月日仍然適用等),你應該看到你期待什麼:) – ThisGuyHasTwoThumbs

+1

它填充缺失數據與今天的數據(第31天),並進行調整以跳過無效日期。很有幫助,就像大多數日期函數在PHP中一樣。 –

回答

7

默認情況下,PHP會使用當前日期/時間值填充缺失的日期值;所以

$date = \DateTime::createFromFormat('m/Y', '02/2017'); 

將填充與當前日期丟失一天的值;截至2月31日是無效日期,它將前進到3月份。同樣,小時/分鐘/秒將根據當前時間填入缺少的時間值。

如果你想強制的行爲迫使以月/時間開始的,然後修改你的面具與一家領先的!

$date = \DateTime::createFromFormat('!m/Y', '02/2017'); 

這將填充缺失的日與本月1日起,並用00:00:00

可替代地,時間,後|將具有相同的效果

$date = \DateTime::createFromFormat('m/Y|', '02/2017'); 
+0

非常感謝您的回答。這是我將在下次知道的東西:) – Whiplash

+0

'!'和'|'語法很棒,而且似乎已經存在了很長時間(https://3v4l.org/YvIkt)。 –

+0

閱讀[確切規格](http://php.net/manual/en/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters)以瞭解'!'和'''代碼是如何工作的? 。基本上他們將值設置爲Unix Epoch - 我們得到第1天,因爲它恰好是1970年1月1日00:00:00 UTC。 –

0

不能存儲不完整的日期,至少不能用於複雜日期計算的專用日期格式(沒有什麼能夠阻止您創建自己的MonthYear類)。所以,當你創建一個信息不完全的東西DateTime()對象需要發生:

  • 崩潰
  • 使用一些默認值

PHP選擇採用第二個選項,並使得從C語言繼承的決定最新的圖書館:

  1. 假設丟失的數據的意思是「現在」
  2. 嘗試解決AUT omatically無效的日期,該算法可以創建

在這種情況下,Feb 2017成爲31 Feb 2017(因爲「現在」是31 May 2017)和PHP遵循這樣一個道理:二月僅在2017年拿到了28天,但我有三個以上;用戶可能想要將這三天額外的時間移到3月份。因此3 Mar 2017

我看不出有任何理由,以避免硬編碼01因爲,畢竟,這是一個硬編碼值(爲什麼這個月的第一天,而不是最後一個或任何其他一天?)。

$input = '05/2017'; 
$date = \DateTime::createFromFormat('d/m/Y', "01/$input"); 
+0

感謝您對功能的詳細說明!事情是,我總是試圖避免硬編碼值,但這次看起來PHP做同樣的事情。我想硬編碼'01'與添加'!m/Y'相同,如上面的答案中所解釋的。 – Whiplash

+0

本質上是。但直到今天,我甚至都不知道你可以使用'!'。 –

+0

我的意思是說,馬克貝克的答案建議使用'!',事實證明它做同樣的事情:)再次感謝你。 – Whiplash