# DateTimeInterface is not a usable interface?

- Thread: https://externals.io/message/87217
- Original archive: https://news-web.php.net/php.internals/87217
- Started by Marco Pivetta on 2015-07-21T11:01:06+00:00
- Messages: 7
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #87218 — Niktia Nefedov — 2015-07-21T10:05:54+00:00

URL: https://externals.io/message/87217#87218 · In reply to: #87217

On Tue, 21 Jul 2015 15:01:06 +0400, Marco Pivetta <ocramius@gmail.com>  
wrote:

> Hello,
>
> I was looking at DateTimeInterface in order to provide my own
> implementation of it, when I hit this:
>
> http://3v4l.org/8GvgO
>
> > […]
> in"
>
> Is there any actual reason for this kind of limitation?
> Can it be removed before going stable?
>
> I also wasn't able to find any RFC information around it on
> https://wiki.php.net/rfc#php_55 - is there any previous discussion around
> this, or did it just sneak its way in?
>
> Greets,
>
> Marco Pivetta
>
> http://twitter.com/Ocramius
>
> http://ocramius.github.com/

Hey Marco,

The discussion was here https://github.com/php/php-src/pull/512

tl;dr core functions that accept DateTime and DateTimeImmutable  
(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 call  
UserDefinedDateTime#diff in the end which would need to implement the  
logic.

---

## #87217 — Marco Pivetta — 2015-07-21T11:01:06+00:00

URL: https://externals.io/message/87217#87217

Hello,

I was looking at DateTimeInterface in order to provide my own
implementation of it, when I hit this:

http://3v4l.org/8GvgO

 > "Fatal error: DateTimeInterface can't be implemented by user classes in"

Is there any actual reason for this kind of limitation?
Can it be removed before going stable?

I also wasn't able to find any RFC information around it on
https://wiki.php.net/rfc#php_55 - is there any previous discussion around
this, or did it just sneak its way in?

Greets,

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

---

## #87219 — Marco Pivetta — 2015-07-21T11:14:50+00:00

URL: https://externals.io/message/87217#87219 · In reply to: #87218

Hey Niktia,



> There's a workaround though - it's to always call user-defined class's
> method directly from built-in functions
>

That's not the workaround, that's the actual fix: the current fix breaks
the OO model basics by introducing a limitation in the interface, rather
than in the broken implementations.

Greets,

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

---

## #87220 — Marco Pivetta — 2015-07-21T11:25:36+00:00

URL: https://externals.io/message/87217#87220 · In reply to: #87219

I should also add that this breaking change was introduced in a patch
release (5.5.8).
What has happened has happened, and I don't want to blame anyone, but this
is actually really broken :-\

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/



> Hey Niktia,
>
> 
>
> > […]
>
> That's not the workaround, that's the actual fix: the current fix breaks
> the OO model basics by introducing a limitation in the interface, rather
> than in the broken implementations.
>
> Greets,
>
> Marco Pivetta
>
> http://twitter.com/Ocramius
>
> http://ocramius.github.com/

---

## #87221 — Derick Rethans — 2015-07-21T11:56:50+00:00

URL: https://externals.io/message/87217#87221 · In reply to: #87220

> I should also add that this breaking change was introduced in a patch
> release (5.5.8).

That wasn't good, but I don't see how it was a *breaking* change. It 
never worked before this change either. You now just told you're doing 
something inappropriate.

> What has happened has happened, and I don't want to blame anyone, but 
> this is actually really broken :-\

It's not a check that can be easily removed though. As Nikita says, this 
all operate on internal structures. DateTimeInterface is meant so that 
both DateTime and DateTimeImmutable can be type hinted for, and not 
really for user land. Retrofitting PHP's DateTime stuff with user 
extended classes and implementations is not going to be a trivial thing.

cheers,
Derick

---

## #87222 — Marco Pivetta — 2015-07-21T12:29:12+00:00

URL: https://externals.io/message/87217#87222 · In reply to: #87221

> 
>
> > […]
>
> That wasn't good, but I don't see how it was a *breaking* change. It
> never worked before this change either. You now just told you're doing
> something inappropriate.
>

It's an interface, it doesn't "work", it simply gets implemented (then the
implementing code "works").


> > […]
>
> It's not a check that can be easily removed though. As Nikita says, this
> all operate on internal structures. DateTimeInterface is meant so that
> both DateTime and DateTimeImmutable can be type hinted for, and not
> really for user land. Retrofitting PHP's DateTime stuff with user
> extended classes and implementations is not going to be a trivial thing.
>

Then make DateTime and DateTimeImmutable only interact with DateTime and
DateTimeImmutable (or child classes), but don't rely on the interface if
you're not actually respecting it internally in first place, no?

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

---

## #87223 — Rowan Collins — 2015-07-21T13:36:39+00:00

URL: https://externals.io/message/87217#87223 · In reply to: #87222

Marco Pivetta wrote on 21/07/2015 13:29:
> Then make DateTime and DateTimeImmutable only interact with DateTime and
> DateTimeImmutable (or child classes), but don't rely on the interface if
> you're not actually respecting it internally in first place, no?

What exactly are you suggesting? That DateTimeInterface shouldn't exist 
at all?

It's useful to be able to check if a given variable is an instance of 
either DateTime or DateTimeImmutable, and an Interface is an obvious way 
to do this, regardless of what else can be done with that interface.

As you can see here: http://3v4l.org/SU1Xq this was definitely a bug in 
early 5.5.x releases (the error is a frankly baffling "Fatal error: 
DateTime::diff() must be derived from DateTimeImmutable::diff"), so the 
change in behaviour in a point release seems justified. HHVM apparently 
still allows the implementation, then fatals when you try to diff 
against it.

So, userland implementations of the interface have never worked; it 
might be nice to add the ability in, but in answer to the original 
question, yes, there's a reason behind this limitation.

Regards,
-- 
Rowan Collins
[IMSoP]
