使 DateTime::createFromFormat() 返回子类而不是父类

发布于 2024-10-26 10:19:03 字数 490 浏览 6 评论 0原文

我正在扩展 DateTime 并添加一些有用的方法和常量。

当使用 new 创建新对象时,一切都很好,但是当使用静态方法 createFromFormat 时,它总是返回原始的 DateTime 对象,当然没有的子方法可用。

我正在使用以下代码来规避此问题。这是最好的方法吗?

namespace NoiseLabs\DateTime;

class DateTime extends \DateTime
{
    static public function createFromFormat($format, $time)
    {
        $ext_dt = new self();

        $ext_dt->setTimestamp(parent::createFromFormat($format, time)->getTimestamp());

        return $ext_dt;
    }
}

I'm extending DateTime do add some useful methods and constants.

When using new to create a new object everything is fine but when using the static method createFromFormat it always returns the original DateTime object and of course none of the child methods are available.

I am using the following code to circumvent this issue. Is this the best approach?

namespace NoiseLabs\DateTime;

class DateTime extends \DateTime
{
    static public function createFromFormat($format, $time)
    {
        $ext_dt = new self();

        $ext_dt->setTimestamp(parent::createFromFormat($format, time)->getTimestamp());

        return $ext_dt;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

黒涩兲箜 2024-11-02 10:19:03

这是要走的路。但是,由于您似乎想要做的是使 DateTime 类可扩展,因此我建议您使用 static 而不是 self

namespace NoiseLabs\DateTime;

class DateTime extends \DateTime
{
    static public function createFromFormat($format, $time)
    {
        $ext_dt = new static();
        $parent_dt = parent::createFromFormat($format, $time);

        if (!$parent_dt) {
            return false;
        }

        $ext_dt->setTimestamp($parent_dt->getTimestamp());
        return $ext_dt;
    }
}

如果您不这样做,则没有必要计划延长课程时间,但如果有人这样做,这将阻止他再次采取相同的解决方法。

This is the way to go. However, since what seems you want to do is to render the DateTime class extensible, I'd suggest you use static instead of self:

namespace NoiseLabs\DateTime;

class DateTime extends \DateTime
{
    static public function createFromFormat($format, $time)
    {
        $ext_dt = new static();
        $parent_dt = parent::createFromFormat($format, $time);

        if (!$parent_dt) {
            return false;
        }

        $ext_dt->setTimestamp($parent_dt->getTimestamp());
        return $ext_dt;
    }
}

It's not necessary if you don't plan on extending the class, but if someone ever does, it will prevent him from having to do the same workaround again.

勿忘初心 2024-11-02 10:19:03

我认为你的解决方案很好。另一种方法(只是重构了一点)是这样的:

public static function fromDateTime(DateTime $foo)
{
  return new static($foo->format('Y-m-d H:i:s e')); 
}

public static function createFromFormat($f, $t, $tz)
{
  return static::fromDateTime(parent::createFromFormat($f, $t, $tz));
}

我不确定实现 fromDateTime 的最佳方法是什么。你甚至可以把你拥有的东西放在那里。只要确保不要丢失时区即可。

请注意,您甚至可以实现 __callStatic 并使用一些反射来使其面向未来。

I think your solution is fine. An alternative way (just refactored a bit) is this:

public static function fromDateTime(DateTime $foo)
{
  return new static($foo->format('Y-m-d H:i:s e')); 
}

public static function createFromFormat($f, $t, $tz)
{
  return static::fromDateTime(parent::createFromFormat($f, $t, $tz));
}

I'm not sure what the best way to implement the fromDateTime is. You could even take what you've got and put it in there. Just make sure not to lose the timezone.

Note that you could even implement __callStatic and use a bit of reflection to make it future proof.

澉约 2024-11-02 10:19:03

以前的解决方案忽略了时区和微秒,所以我的一点改进就在这里。
我更喜欢变体 1,但就性能而言,变体 2 在旧 PHP 上可能会快一点。

class NDateTimeImmutable extends \DateTimeImmutable
{
    public static function createFromFormat1($format, $time)
    {
        $parent = parent::createFromFormat($format, $time);
        if (!$parent) {
            return false;
        }
        //Seting timezone like this and not by format to preserve timezone format
        $static = new static($parent->format('Y-m-d\TH:i:s.u'), $parent->getTimezone());
        return $static;
    }

    public static function createFromFormat2($format, $time)
    {
        $parent = parent::createFromFormat($format, $time);
         if (!$parent) {
            return false;
        }
        $serialized = serialize($parent);
        // numbers can be computed by strlen() 
        // eg. strlen(parent::class) = 17 but it is slow
        $serialized = strtr($serialized, ['17:"'.parent::class => '18:"'.static::class]);
        return unserialize($serialized);
    }
}

Previous solutions neglect time zones and microseconds, so my little improve is here.
I prefer variant 1, but in terms of performance 2 can be little faster on old PHPs.

class NDateTimeImmutable extends \DateTimeImmutable
{
    public static function createFromFormat1($format, $time)
    {
        $parent = parent::createFromFormat($format, $time);
        if (!$parent) {
            return false;
        }
        //Seting timezone like this and not by format to preserve timezone format
        $static = new static($parent->format('Y-m-d\TH:i:s.u'), $parent->getTimezone());
        return $static;
    }

    public static function createFromFormat2($format, $time)
    {
        $parent = parent::createFromFormat($format, $time);
         if (!$parent) {
            return false;
        }
        $serialized = serialize($parent);
        // numbers can be computed by strlen() 
        // eg. strlen(parent::class) = 17 but it is slow
        $serialized = strtr($serialized, ['17:"'.parent::class => '18:"'.static::class]);
        return unserialize($serialized);
    }
}

久伴你 2024-11-02 10:19:03
class DateTimeEx extends DateTime
{
    static public function createFromFormat($format, $time, $object = null)
    {
        return new static(DateTime::createFromFormat($format, $time, $object)->format(DateTime::ATOM));
    }
}
class DateTimeEx extends DateTime
{
    static public function createFromFormat($format, $time, $object = null)
    {
        return new static(DateTime::createFromFormat($format, $time, $object)->format(DateTime::ATOM));
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文