【问题标题】:PHP DateTime::createFromFormat DATE_ATOM ISO 8601PHP DateTime::createFromFormat DATE_ATOM ISO 8601
【发布时间】:2019-02-21 09:57:46
【问题描述】:

我正在使用PHP 7.2,并尝试从字符串创建日期,如下所示:

$dateString = '2018-12-31T01:01:01+00:00';
$converted  = DateTime::createFromFormat(DATE_ATOM), $dateString);

上面的 sn-p 工作正常并返回预期的结果。

当我在上面提供的日期字符串中交换日期和月份时会出现问题,如下所示:

$dateString = '2018-31-12T01:01:01+00:00';
$converted  = DateTime::createFromFormat(DATE_ATOM), $dateString);

我期待第二个示例返回 false,但我得到了一个实际的日期时间,2020-07-12 01:01:01.000000

所以,我无法判断第二个日期是否是正确的日期,因为系统接受了它,我将在我的数据库中保存一些我不应该保存的东西。

这会被认为是PHP 7.2 中的错误吗?

【问题讨论】:

  • 我觉得不可能,你需要知道哪些数据代表月份,哪些代表日期,否则当今天是
  • 我的意思是检查你之前的日期DateTime::createFromFormat它。 checkdate(31,12,2018) 应该返回 false。如果是这样,请不要转换它。
  • 那么,如果有人选择 8 月和 9 日会发生什么。这是一个有效的日期,但它是错误的,因为您告诉 PHP 创建日期的格式与您提供的字符串不同。这是不可能的
  • 那么您需要按照建议使用checkdate() 之类的东西。 PHP 正在尝试弥补您的错误。它会看到 31 个月,但知道它不能大于 12,因此它会将 19 (3​​1 - 12) 个月添加到您提供的日期
  • 嗯,类似3v4l.org/Ja2RM ??还是我没听懂?

标签: php datetime iso8601


【解决方案1】:

这会被认为是 PHP 7.2 中的错误吗?

不,这是有意实施该方法的方式。你可以争论这是否是实现它的正确方式,但它就是这样。值得注意的是,即使我们都同意它不在这里,它仍然会在实施时继续工作。

这里的实际答案是编写一个验证器(针对整个格式和所有部分)并通过它运行任何不受信任的输入。

【讨论】:

  • 我仍然认为这不是函数的预期行为。如果函数被指示将日期解析为DATE_ATOM(或任何其他格式),并且该值不是该格式,则它应该返回false,而不是尝试解析日期并返回垃圾数据。
猜你喜欢
  • 2017-11-01
  • 2012-04-24
  • 1970-01-01
  • 1970-01-01
  • 2011-07-20
  • 1970-01-01
  • 1970-01-01
  • 2013-06-09
  • 2014-08-07
相关资源
最近更新 更多