2017-05-31 34 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

相关问题