【问题标题】:Failed to parse time string at position 41 (i): Double timezone specification无法解析位置 41 (i) 的时间字符串:双时区规范
【发布时间】:2012-11-05 11:25:46
【问题描述】:

我正在使用 jquery daterangepicker,而后者又使用 jQuery datapicker

我的 Ubuntu 系统运行良好。浏览器正在发送一个可解析的字符串:

$dateStarted = new \DateTime($post['startDate']); // Thu Nov 15 2012 00:00:00 GMT-0700 (MST)
print_r($dateStarted);

输出:

DateTime Object
(
    [date] => 2012-11-15 00:00:00
    [timezone_type] => 1
    [timezone] => -07:00
)

在我们的测试人员 Windows 系统上,浏览器正在字符串中发送扩展时区:

$dateStarted = new \DateTime($post['startDate']); // Thu Nov 15 2012 00:00:00 GMT-0700 (Mountain Standard Time)
print_r($dateStarted);

抛出和异常:

Exception: DateTime::__construct(): Failed to parse time string 
 (Thu Nov 15 2012 00:00:00 GMT-0700 (Mountain Standard Time)) 
 at position 41 (i): Double timezone specification

我在 Google 上四处搜索,但找不到有关此特定 PHP 错误的任何资源。

我正在通过删除返回相同结果的括号文本来“解决”这个问题:

$dateString = strstr($dateString, " (", true); // Thu Nov 15 2012 00:00:00 GMT-0700

这似乎很糟糕,我正在寻找有关如何正确执行此操作的建议。

【问题讨论】:

  • 尝试->createfromformat(),并将这两个时区之一设为“噪音”,以便解析器忽略它。您会收到警告,因为可能会发生 TZ 冲突(例如,错误地构建了显示 GMT +0800 (EDT) 的字符串。)
  • 我相信引导日期选择器(github.com/eternicode/bootstrap-datepicker)使用相同的基础。事实证明,当您询问所选日期时,它将返回一个 javascript Date 对象。您可以让此对象返回一个 UTC 字符串,该字符串在浏览器中始终具有相同的格式,并且可以由新的 \DateTime 解析。这样做:`var dateString = yourDate.toUTCString();'

标签: php jquery


【解决方案1】:

我会说这是一个错误。使用此字符串时,您会遇到相同的错误

$dateStarted = new \DateTime("Thu Nov 15 2012 00:00:00 GMT-0700 (abcdefg)");

少一个

$dateStarted = new \DateTime("Thu Nov 15 2012 00:00:00 GMT-0700 (abcdef)");

它被“正确”解析。

似乎时区字符串限制为 6 个字符。除非您能够并且愿意配置您的 Windows 客户端,否则我会说剥离“时区”是一个可行的“解决方案”。

【讨论】:

  • 现在是 2018 年,问题仍然存在。对于它的价值,您可以将日期字符串剪辑为长度 33。排除所有垃圾,并且像魅力一样工作。
【解决方案2】:

按照 Marc B 的建议使用 DateTime::createFromFormat() 似乎是一个更好的解决方案。

我最终得到的是:

$dateStarted = \DateTime::createFromFormat('D M d Y H:i:s e+', $post['startDate']); // Thu Nov 15 2012 00:00:00 GMT-0700 (Mountain Standard Time)
print_r($dateStarted);
print_r(\DateTime::getLastErrors());

现在输出正确的日期:

DateTime Object
(
    [date] => 2012-11-15 00:00:00
    [timezone_type] => 1
    [timezone] => -07:00
)

Array
(
    [warning_count] => 1
    [warnings] => Array
        (
            [33] => Trailing data
        )

    [error_count] => 0
    [errors] => Array
        (
        )

)

格式末尾的+ 是使这项工作发挥作用的魔力。

【讨论】:

  • @OlafDietsche 谢谢!有一个警告。这适用于 PHP 5.3.10 而不是 5.3.2。我怀疑+ 运算符有一个已修复的错误。
  • @imperium2335 就在文档中:If this format specifier is present, trailing data in the string will not cause an error, but a warning instead
【解决方案3】:

我在 php 7.2 和 laravel 5.6 中工作。大多数upvoted unswer 不起作用,因为在这个php 版本中找不到该方法。 (我不确定,但它给出了一个错误,说找不到该方法)。 但相反,有一种方法与解决原始问题的方法完全相同(将 javascript 日期对象转换为时间戳)。

$fromDate = date_create_from_format('D M d Y H:i:s e+', $fromDate);

这可以用于数据库查询或作为日期对象。

【讨论】:

  • 你的答案只是接受答案的程序方法。
  • 是的。但是我想在这里添加它,因为它帮助我解决了它与以前的抱怨的地方。我认为这个答案稍后会编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-29
  • 2019-09-07
  • 2013-08-25
  • 2019-11-08
  • 2013-07-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多