如何在DateInterval扩展类中创建days属性?

3

我希望扩展DateInterval类以添加自己的方法。为此,我想从DateInterval对象创建一个DateIntervalEx扩展类实例。 例如:

$dateInterval = date_create('yesterday')->diff(date_create('today 13:24'));

$diEx = new DateIntervalEx($dateInterval);

我为这门课做出的尝试:

class DateIntervalEx extends Dateinterval{
  public function __construct(DateInterval $interval){
    parent::__construct('P0D');

    foreach($interval as $prop => $value){
      $this->$prop = $value;
    }
  }
}

diff()方法返回一个DateInterval对象,其中$days == 1

DateInterval::__set_state(array(
   'y' => 0,
   'm' => 0,
   'd' => 1,
   'h' => 13,
   'i' => 24,
   's' => 0,
   'f' => 0.0,
   'weekday' => 0,
   'weekday_behavior' => 0,
   'first_last_day_of' => 0,
   'invert' => 0,
   'days' => 1,
   'special_type' => 0,
   'special_amount' => 0,
   'have_weekday_relative' => 0,
   'have_special_relative' => 0,
))

但是我的扩展类返回的是 days => false。

DateIntervalEx::__set_state(array(
   'weekday' => 0,
   'weekday_behavior' => 0,
   'first_last_day_of' => 0,
   'days' => false,
   'special_type' => 0,
   'special_amount' => 0,
   'have_weekday_relative' => 0,
   'have_special_relative' => 0,
   'y' => 0,
   'm' => 0,
   'd' => 1,
   'h' => 13,
   'i' => 24,
   's' => 0,
   'f' => 0.0,
   'invert' => 0,
))

我该如何将days属性设置为正确的值?


2
不确定是否可能。https://www.php.net/manual/en/class.dateinterval.php#dateinterval.props.days: “[days] 如果 DateInterval 对象是由 DateTime::diff() 创建的,则这是开始日期和结束日期之间的总天数。否则,days 将为 FALSE。” - CBroe
即使我将您的构造函数内容替换为parent::__construct($interval->format('P%yY%mM%dDT%hH%iM%sS'));,结果仍然相同 - 结果对象中的“days”为false。 - CBroe
1个回答

2
无法在 PHP 中实现。
如果 DateInterval 是使用 DateTime::diff() 创建的,那么 PHP 运行时将设置 $days 属性,如您在文档中所看到的:

天数

如果 DateInterval 对象是由 DateTime::diff() 创建的,则这是起始日期与结束日期之间的总天数。否则,天数将为 FALSE。

在 PHP 5.4.20/5.5.4 之前,您将在访问属性时收到 -99999 而不是 FALSE。

请查看两个重要的 DateTime 扩展项目如何处理此问题(例如,它们没有):
Chronos (ChronosInterval 扩展了 DateTimeInterval):
/**
 * Create a ChronosInterval instance from a DateInterval one.  Can not instance
 * DateInterval objects created from DateTime::diff() as you can't externally
 * set the $days field.
 *
 * @param \DateInterval $di The DateInterval instance to copy.
 * @throws \InvalidArgumentException
 * @return static
 */
public static function instance(DateInterval $di): self
{
   if (static::wasCreatedFromDiff($di)) {
       throw new InvalidArgumentException(
           "Can not instance a DateInterval object created from DateTime::diff()."
       );
}
// ...

Carbon(CarbonInterval)是从DateTimeInterval继承而来的。

/**
 * Create a CarbonInterval instance from a DateInterval one.  Can not instance
 * DateInterval objects created from DateTime::diff() as you can't externally
 * set the $days field.
 *
 * @param DateInterval $interval
 *
 * @return static
 */
public static function instance(DateInterval $interval)
{
    return self::castIntervalToClass($interval, static::class);
}

您可以在这里查看相关的C代码。


1
我想我必须接受这个事实。感谢您提供详细的答案。 - jspit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接