【问题标题】:PHP DateTime::createFromFormat behavoiurPHP DateTime::createFromFormat 行为
【发布时间】:2017-11-01 04:00:55
【问题描述】:

今天,\DateTime::createFromFormat 函数的行为让我感到困惑。

在我的例子中,我有一个字符串,以下列格式表示日期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 函数是否缺少有关如何创建对象的信息?我对此很困惑。提前感谢大家的帮助!

【问题讨论】:

  • 这只是创建对象 var_dump $date->format() (格式与日期相同,因此 Ymd 仍然适用等),你应该看到你所期望的 :)跨度>
  • 它用今天的数据(第 31 天)填充缺失的数据,并调整以跳过无效日期。有用与否,就像大多数日期函数在 PHP 中一样。

标签: php date datetime


【解决方案1】:

默认情况下,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');

【讨论】:

  • 非常感谢您的回答。这是我下次会知道的事情:)
  • !| 语法很棒,似乎已经存在于 quite long
  • 阅读exact specs 以了解!| 代码的工作原理很有趣。基本上他们将值设置为 Unix 纪元——我们得到第 1 天,因为它恰好是 1970 年 1 月 1 日 00:00:00 UTC。
【解决方案2】:

您不能存储不完整的日期,至少不能以可用于复杂日期计算的专用日期格式存储(没有什么能阻止您创建自己的 MonthYear 类)。因此,当您创建一个信息不完整的DateTime() 对象时,需要发生一些事情:

  • 崩溃
  • 使用一些默认值

PHP 选择第二个选项,并做出继承自 C 语言日期库的决定:

  1. 假设缺失数据意味着“现在”
  2. 尝试自动修复此算法可以创建的无效日期

在这种情况下,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");

【讨论】:

  • 感谢您对功能的详细解释!问题是我总是尽量避免硬编码值,但这次 PHP 似乎做了同样的事情。我猜硬编码 '01' 与添加 '!m/Y' 相同,如上述答案中所述。
  • 基本上是这样。但直到今天我才知道你可以使用!
  • 我的意思是马克贝克的回答建议使用!,结果证明它做同样的事情:) 非常感谢,再次。
猜你喜欢
  • 2012-04-24
  • 1970-01-01
  • 2011-07-20
  • 1970-01-01
  • 1970-01-01
  • 2013-06-09
  • 2014-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多