Recently, I discovered that there is a DateTimeInterface
. As I was working with \DateTime
and \DateTimeImmutable
, I thought that it'd be good to typehint for.
Yet on the Changelog on php.net it says that since 5.5.8:
Trying to implement DateTimeInterface raises a fatal error now. Formerly implementing the interface didn't raise an error, but the behavior was erroneous.
This reads that I never be able to implement my own CustomDateTime
class implementing the DateTimeInterface
, which seems rather odd.
Should I use the DateTimeInterface
in my userland code?
My gut feeling tells me not to. Yet it also doesn't feel right to typehint the object, i.e.
@var \DateTime|\DateTimeImmutable|\MyCustomDateTime
You can use the DateTimeInterface
typehint when you expect either one of the native DateTime variants, e.g. \DateTime
or \DateTimeImmutable
.
But as the docs say
It is not possible to implement this interface with userland classes.
So if you plan to implement \DateTimeInterface
with your own implementation, this will not work, e.g.
class MyDateTime implements \DateTimeInterface {} // will raise an error
However, you can create your own interface and adapt the native DateTime classes.
interface MyDateTime { /* some methods */ }
class NativeDateTime implements MyDateTime
{
private $dateTime;
public function __construct($args = 'now') {
$this->dateTime = new \DateTimeImmutable($args);
}
/* some methods */
}
Or you can extend the native DateTime variants, which will then implement the DateTimeInterface
obviously, e.g.
class MyDateTime extends \DateTimeImmutable
{
/* your modifications */
}
var_dump(new MyDateTime instanceof \DateTimeInterface); // true
Details why you cannot implement your own classes implementing \DateTimeInterface
:
tl;dr core functions that accept
DateTime
andDateTimeImmutable
(DateTimeInterface
basically) operate directly on timelib structures hence they will break if you pass them a user-defined class. There's a workaround though - it's to always call user-defined class's method directly from built-in functions, so if you would call(new DateTime())->diff(new UserDefinedDateTime())
it would callUserDefinedDateTime#diff
in the end which would need to implement the logic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With