【问题标题】:PHP DateTime gives incorrect valuePHP DateTime 给出不正确的值
【发布时间】:2018-05-20 09:59:55
【问题描述】:

我想知道为什么这个 php 代码给出了不正确的输出值。

dd(new \DateTime("1397/02/29", new \DateTimeZone('Asia/Tehran')));

它输出以下对象:

DateTime @-18076965944 {#1256 ▼
  date: 1397-03-01 00:00:00.0 Asia/Tehran (+03:25)
}

如您所见,日期不正确,必须是1397-02-01。 值1397/02/30 && 1397/02/31 的输出也不正确。

谁能帮忙。 谢谢。

【问题讨论】:

  • 我怀疑今年有 2 月 29 日。
  • @u_mulder 这是一个波斯日期并退出。
  • 我想DateTime 类不支持你的日历。

标签: php datetime persian persian-calendar jalali-calendar


【解决方案1】:

DateTime 闰年代码适用公历规则,它们不适用于波斯历。

“除以 4 但不是 100,除了 400”规则对波斯历无效,它遵循不同的算法:

https://www.timeanddate.com/date/iran-leap-year.html

基本上,您不能将DateTime 用于波斯日期。另见here。你可能会适应some other code

更新:实际上,似乎不同的日历和来源不同意闰年。 Jalali 有 1397 作为闰年,但波斯历没有?

【讨论】:

    【解决方案2】:

    PHP 将日期对象内部存储为结构 https://github.com/php/php-src/blob/master/ext/date/php_date.h#L137 https://github.com/php/php-src/blob/master/ext/date/lib/timelib.h#L204

    但是 DateTime init 没有验证,只将给定的日期字符串转换为时间戳。 https://github.com/php/php-src/blob/master/ext/date/php_date.c#L2647

    在创建日期对象之前,您应该使用http://php.net/manual/en/function.checkdate.php检查它

    var_dump(
        checkdate(2,20,1000), // bool(true)
        checkdate(2,30,1000) // bool(false)
    );
    

    【讨论】:

    • 它没有解决问题,checkdate()函数验证Gregorian 日期,但我使用的日期是Jalali
    【解决方案3】:

    感谢大家的回复。

    当我要将Jalali 日期转换为Gregorian 日期时,我试图将我的Jalali 日期字符串("1397/02/29") 创建一个PHP DateTime 对象,然后将日期对象转换为Gregorian 使用 this package 的日期对象。我通过使用morilog/jalali 直接将我的Jalali 日期字符串转换为我想要的,如下所示:

    $jalali_date = explode("/", request()->to);
    
    $gregorian_date_time = \jDateTime::toGregorianDate($jalali_date[0], $jalali_date[1], $jalali_date[2])->setTime(23, 55)->format("Y-m-d H:i");
    return $gregorian_date_time;
    

    再次感谢大家。

    【讨论】:

      猜你喜欢
      • 2013-05-05
      • 2022-01-19
      • 2018-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多