[PSR-20] Feedback for the ClockInterface

214 views
Skip to first unread message

Andreas Heigl

unread,
Sep 12, 2021, 1:54:33 PM9/12/21
to php...@googlegroups.com
Hey all.

Some months of work have past for the Working Group for PSR-20
(ClockInterface).

By now our idea of the interface has stabilized, a lot of internal
decissions have been made and a lot of discussion with different people
– especially maintainers of different clock implementations – have been
done and had their influence on the interface and on the meta-document
associated with it.

Time to open up the discussion to the list and to external feedback.

Please give feedback regarding the Interface[1] and the
Meta-Document[2]. Either on the PSR-20 Channel on Discord[3], via the
mailinglist or via PullRequests against those two documents.

Cheers

Andreas

[1]
https://github.com/php-fig/fig-standards/blob/master/proposed/clock-meta.md
[2] https://github.com/php-fig/fig-standards/blob/master/proposed/clock.md
[3] https://discord.com/channels/788815898948665366/818850995186171918
--
,,,
(o o)
+---------------------------------------------------------ooO-(_)-Ooo-+
| Andreas Heigl |
| mailto:and...@heigl.org N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org |
+---------------------------------------------------------------------+
| https://hei.gl/appointmentwithandreas |
+---------------------------------------------------------------------+

OpenPGP_0xA8D5437ECE724FE5.asc
OpenPGP_0xA8D5437ECE724FE5.asc
OpenPGP_signature

Larry Garfield

unread,
Sep 13, 2021, 10:26:45 AM9/13/21
to PHP-FIG
On Sun, Sep 12, 2021, at 12:53 PM, Andreas Heigl wrote:
> Hey all.
>
> Some months of work have past for the Working Group for PSR-20
> (ClockInterface).
>
> By now our idea of the interface has stabilized, a lot of internal
> decissions have been made and a lot of discussion with different people
> – especially maintainers of different clock implementations – have been
> done and had their influence on the interface and on the meta-document
> associated with it.
>
> Time to open up the discussion to the list and to external feedback.
>
> Please give feedback regarding the Interface[1] and the
> Meta-Document[2]. Either on the PSR-20 Channel on Discord[3], via the
> mailinglist or via PullRequests against those two documents.
>
> Cheers
>
> Andreas
>
> [1]
> https://github.com/php-fig/fig-standards/blob/master/proposed/clock-meta.md
> [2] https://github.com/php-fig/fig-standards/blob/master/proposed/clock.md
> [3] https://discord.com/channels/788815898948665366/818850995186171918

I filed a small PR with some typo fixes. Nothing major.

Overall I like the simplicity of it. My main concern is, unsurprisingly, around the timezone question, and usability.

Right now, if I want "now" I can just call `new DateTimeImmutable('now', new DateTimeZone('whatever'))` directly. It's a single call.

With the proposed interface, I will virtually always need to create TWO DTI objects; one that gets returned by now(), and one returned by calling setTimezone() on it. (Because I never trust what the system timezone is set to, and neither should you.) That is slightly less performant, and also clunkier feeling. And that means people will forget to do it.

I fear that, in its current form, we'll end up with a lot of people assuming the timezone they get back from now() is reasonable, when in fact it's not defined at all, and end up with subtle bugs.

--Larry Garfield

Woody Gilk

unread,
Sep 13, 2021, 10:39:11 AM9/13/21
to PHP Framework Interoperability Group
I feel like the timezone concerns are not as dire as they might initially seem, because:

1. It is easy to wrap this interface with a local implementation that will always return the date object in (eg) UTC. It's about 3 actual lines of code.
2. In environments that we (really do) control, we can set `date.timezone` and not have to think about it again.

That being said, I think it would also be reasonable for `ClockInterface::now()` to ALWAYS return a date in UTC timezone. That would create a stronger definition and eliminate most concerns about time zones.
 

--Larry Garfield

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/f74c10e6-79ea-4113-913c-b79ded8407d3%40www.fastmail.com.

Chuck Burgess

unread,
Sep 13, 2021, 10:45:49 AM9/13/21
to php...@googlegroups.com
I think I remember most/all of the working group projects argued against the TZ piece. The metadoc specifically says TZ is not included... maybe that section should go deeper into the decision... ?
CRB

Andreas Heigl

unread,
Sep 13, 2021, 11:09:25 AM9/13/21
to php...@googlegroups.com
Hey Larry, Hey All.
We've discussed that back and forth as well.

In the end there are two reasons why we decided to ignore timezones:

1. We can not enforce a specific timezone via the return type. The only
thing we *can* enforce is that it is a DateTimeImmutable object. But we
can not enforce what timezone it is set in. Additionally no matter what
timezone it is set, it will anyhow describe a specific point in time -
which is what we care about in the end. If the Busines-Logic needs that
in a specific timezone it is also the task of the business-logic to
ensure that.

2. Depending on the Clock that is uses one can make sure that only
DateTimeImmutable objects of a specified timezone are returned on
calling `ClockInterface::now()`. So there can be an implicit contract to
always have a DateTimeImmutable Object with a defined timezone.

Besides those two reasons there is usually only a conversion into a
certain timezone necessary when displaying the data. That is the only
reason to actually modify the timezone. If you need the timestamp you
can always use `DateTimeImmutable::getTimestamp()` and per definition
that will always be in UTC. so there is no need to actually modify the
timezone to UTC before.

All that made it reasonable to ignore the timezone aspect.

Does that clarify the case?

Cheers

Andreas
OpenPGP_0xA8D5437ECE724FE5.asc
OpenPGP_signature

Andreas Heigl

unread,
Sep 13, 2021, 11:16:20 AM9/13/21
to php...@googlegroups.com
Nope.

If you are actually using timezones (Timezone type 3) then there is no
need to convert to UTC. On the contrary, it might be a bad idea to
convert everything to UTC or to use only UTC[1].

The second reason why that would not be a good idea is that we can not
guarantee that a DateTimeImmutable object returned by
`ClockInterface:now()` is actually with timezone UTC.

And even if so: 12:00:00 UTC, 14:00:00+02:00 and 10:00:00-02:00 are all
different expressions of the same point in time. And
`DateTimeImmutable::now()` returns something that describes a point in
time. If the busines-logic needs that point in time also in a specific
timezone, then it is the task of the business-logic to ensure that.

Cheers

Andreas

PS:Personal opinion: From what I have seen so far, a lot of the hassle
with timezones comes from people trying to do something with it while
not understanding it and thereby making it (much) worse... ;-)

[1]
https://andreas.heigl.org/2016/12/22/why-not-to-convert-a-datetime-to-timestamp/
> --
> Woody Gilk
> https://www.shadowhand.com
>
>
>>
>> --Larry Garfield
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "PHP Framework Interoperability Group" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to php-fig+u...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/php-fig/f74c10e6-79ea-4113-913c-b79ded8407d3%40www.fastmail.com
>> .
>>
>

OpenPGP_0xA8D5437ECE724FE5.asc
OpenPGP_signature

Larry Garfield

unread,
Sep 15, 2021, 1:24:42 PM9/15/21
to PHP-FIG
That article is the most compelling argument I've heard yet for not forcing the return to UTC. An abridged version of the same point should be included in the metadoc.

That the type system cannot guarantee that it's in UTC is irrelevant. Specs can and do require all kinds of things above and beyond what the type system can enforce. That's the purpose of a spec, not just an interface package. :-)

By analogy, though, 1 m, 1000 mm, and 39.370 inches all represent the same length. If I'm asking some service for a length, though, my business logic generally does care about the units. Timezone is, as I conceptualize it, analogous to units in this case.

--Larry Garfield

Andreas Heigl

unread,
Oct 23, 2021, 2:22:22 PM10/23/21
to php...@googlegroups.com
Yes. And as with the lengths your busines logic should make sure that
the numbers as well as the unit match your expectation. Otherwise you
might crash a mars lander[1].

Applied to timezones: When your busines-logic expects the
DAteTimeImmutable object to be in a certain timezone, you need to make
sure that it actually *is* in that expected timezone.

Therefore I'd rather not have any implicit (despite it being documented
in a specification) rules about what kind of state a DateTimeImmutable
object is in.

The explicit contract that the interface can provide, is that it returns
a DateTimeImmutable object. With a set timezone. And it's up to your
business logic then to make sure that that matches your codes expectations.

And yes: We might have a different view here on what a spec might and
might not be able to do. I rather play the *very* safe card ;-)

Cheers

Andreas

[1] https://www.simscale.com/blog/2017/12/nasa-mars-climate-orbiter-metric/
OpenPGP_0xA8D5437ECE724FE5.asc
OpenPGP_signature

Andreas Heigl

unread,
Oct 23, 2021, 3:31:09 PM10/23/21
to php...@googlegroups.com
Hey Larry, Hey List:

On 15.09.21 19:24, Larry Garfield wrote:
> On Mon, Sep 13, 2021, at 10:15 AM, Andreas Heigl wrote:
[…]
>>
>> [1]
>> https://andreas.heigl.org/2016/12/22/why-not-to-convert-a-datetime-to-timestamp/
>
> That article is the most compelling argument I've heard yet for not forcing the return to UTC. An abridged version of the same point should be included in the metadoc.

Done so via https://github.com/php-fig/fig-standards/pull/1257.

I'd be happy about a review and an eventual merge.

Cheers

Andreas
OpenPGP_0xA8D5437ECE724FE5.asc
OpenPGP_signature

daniel...@gmail.com

unread,
Oct 30, 2021, 9:37:46 AM10/30/21
to PHP Framework Interoperability Group
I had experience with such type of time provider (with interface) and we realized that it's very impractical. At first, it looks cool: injecting Clock which may be frozen here and regular there (integration tests with real DI-container, not unit tests), but clock is singleton by its nature. Moreover, sometimes you need time in value objects, e.g. `Uuid::v1()` or domain entities and injecting service to them looks pretty awful.

I suggest concrete class like
```
final class Clock
{
    public static function setup(Closure $clock): void
    {
        // ...
    }

    public static function now(): DateTimeImmutable
    {
        // ...
    }
}
```
Concrete class is still fixes the interoperability problem and looks more practical.

Ben Peachey

unread,
Apr 20, 2022, 5:17:06 PM4/20/22
to PHP Framework Interoperability Group
Hi all!

I have a question regarding the ClockInterface. I wasn't sure if I should reply to this thread or open a new one, so I hope this is okay....

In the original email, Chris Seufert mentions

> Its impossible to mock some calls to date and time without using a PHP extension to override the current time & date.

I've run into this in the past as well (for instance, using TimeCop to "freeze" time in tests). An intermediate (such as the proposed interface) would be very much welcome!

The proposal states the interface provides "basic operation to read the current time and date from the clock".

Has there already been talk of support in the interface (or a separate interface) for non-now time? If so, can someone point me to where I can read up on that?

My reason for asking is that, having an interface for the one but not the other (i.e. for an interface for "now" but not for "then"), would eventually lead to still needing TimeCop (or similar) for the "then" cases.
(Which I would obviously like to avoid, if possible).  

Greeting,
Ben.

Woody Gilk

unread,
Apr 20, 2022, 6:52:24 PM4/20/22
to PHP Framework Interoperability Group
Ben,

In the cases where you need a "then" clock, the same interface could be used with a mock implementation that returns a set time.
--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages