-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New PSR for ClockInterface #1224
Merged
Merged
Changes from all commits
Commits
Show all changes
58 commits
Select commit
Hold shift + click to select a range
31f93b6
Create Clock PSR
cseufert faa28e1
Added Clock PSR Meta
cseufert 0065811
added method to retreieve current timezone
cseufert d6c75b2
Updated timezone return types
cseufert 9974dfb
Update proposed/clock-meta.md to fix typos
cseufert 0c66162
Update proposed/clock-meta.md to fix typos
cseufert abb943b
Update proposed/clock-meta.md to fix typos
cseufert 0df6d63
Update proposed/clock-meta.md to fix typos
cseufert 072514e
Update purpose of document
cseufert 2bc8e21
DateTime is out
cseufert fed0313
Update clock.md fixed typo
cseufert 9c3d13f
Update clock.md update code formatting
cseufert 82f07eb
Update proposed/clock-meta.md
cseufert c8bcefe
Update proposed/clock-meta.md
cseufert 5415f5f
Simplify the ClockInterface
cseufert 3386929
Include example implementations
cseufert 4395fc3
Added names for sponsors and working group
cseufert d1bf6cf
Updated Working Group Members
cseufert 506b1fc
added Luis to WG
cseufert 380089c
Update proposed/clock.md
cseufert 5c17173
Update proposed/clock-meta.md
cseufert 650f6d2
Update proposed/clock-meta.md
cseufert 05f2fba
Update proposed/clock-meta.md
cseufert 18585b5
escape package names
cseufert 8d3e388
clean up relevant links format
cseufert 0ad441a
code formatted interface name
cseufert 078ec7b
Update proposed/clock-meta.md
cseufert 2e13cb5
Update proposed/clock-meta.md
cseufert a79da23
Update proposed/clock-meta.md
cseufert 0d7157c
Update proposed/clock-meta.md
cseufert 4f13a8e
Update proposed/clock.md
cseufert fa9323d
Update proposed/clock.md
cseufert 17f364a
Update proposed/clock.md
cseufert 8a701b2
Update proposed/clock-meta.md
cseufert 509163c
Update proposed/clock-meta.md
cseufert 8b34135
Update proposed/clock-meta.md
cseufert 6bd1916
Update clock-meta.md
cseufert 0338682
Added entrace vote link
cseufert 2734e16
Update proposed/clock-meta.md
cseufert c279903
Update proposed/clock-meta.md
cseufert 6ada868
Update proposed/clock-meta.md
cseufert 4b53d45
Update proposed/clock-meta.md
cseufert 92c4244
Update proposed/clock-meta.md
cseufert 3a8c4b1
Update proposed/clock-meta.md
cseufert 87c4002
Update proposed/clock-meta.md
cseufert 5e05b77
Update proposed/clock-meta.md
cseufert 9f8115b
Update proposed/clock-meta.md
cseufert 1ced885
Update proposed/clock.md
cseufert 12e1c1c
Update proposed/clock.md
cseufert 2de88c5
Update proposed/clock.md
cseufert 9401671
Re-ordered WG member list
cseufert 3688544
Update Reference example implemtations
cseufert 9ef42e5
Fix Order
cseufert 8826633
Removed timezones from usage patterns
cseufert 8e9aace
Update symfony details & added Chronos details
cseufert 66fac09
Update proposed/clock-meta.md
cseufert 81cb449
Update proposed/clock-meta.md
cseufert 3caffc3
Update proposed/clock-meta.md
cseufert File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
# Clock Meta Document | ||
|
||
## 1. Summary | ||
|
||
The purpose of using the `ClockInterface` is to provide a standard way to access the system | ||
time, that would allow interopability when testing code that relies on the current time | ||
rather than relying on installing PHP extensions or use hacks like re-declaring the `time()` | ||
function in other namespaces. | ||
|
||
## 2. Why Bother? | ||
|
||
There are currently a few libraries that provide this functionality, however | ||
there is no interopability between these different libraries, as they ship with their own | ||
clock interfaces. Symfony provides a package called `symfony/phpunit-bridge` that has a | ||
`Symfony\Bridge\PhpUnit\ClockMock` class, which allows mocking PHP's built-in time & date | ||
functions, however this does not solve mocking calls to `new \DateTimeImmutable()`. It does | ||
not fully mock time when called from other libraries that rely on the system time. | ||
`Cake\Chronos\Chronos` does provide mocking, however it is set via a global (static class | ||
property), and this has its own pitfalls as it provides no isolation. | ||
|
||
Pros: | ||
|
||
* Consistent interface to get the current time; | ||
* Easy to mock the wall clock time for repeatablility. | ||
|
||
Cons: | ||
|
||
* Extra overhead and developer effort to get the current time, not as simple as | ||
calling `time()` or `date()`. | ||
|
||
## 3. Scope | ||
|
||
### 3.1 Goals | ||
|
||
* Provide a simple and mockable way to read the current time; | ||
* Allow interoperability between libraries when reading the clock. | ||
|
||
### 3.2 Non-Goals | ||
|
||
* This PSR does not provide a recommendation on how and when to use the concepts | ||
described in this document, so it is not a coding standard; | ||
* This PSR does not provide a recommendation on how to handle timezones when | ||
retrieving the current time. This is left up to the implementation. | ||
|
||
## 4. Approaches | ||
|
||
### 4.1 Chosen Approach | ||
|
||
We have decided to formalize the existing practices, used by several other packages | ||
out in the wild. Some of the popular packages providing this functionality are: | ||
`lcobucci/clock`, `kreait/clock`, `ergebnis/clock`, and `mangoweb/clock`. Some providing | ||
interfaces, and some relying on overloading (extending) the Clock class to mock the | ||
current time. | ||
cseufert marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
### 4.2 Example Implementations | ||
|
||
```php | ||
final class SystemClock implements \Psr\Clock\ClockInterface | ||
{ | ||
public function now(): \DateTimeImmutable | ||
{ | ||
return new \DateTimeImmutable(); | ||
} | ||
} | ||
|
||
// | ||
|
||
final class UTCClock implements \Psr\Clock\ClockInterface | ||
{ | ||
private \DateTimeZone $utcTimeZone; | ||
cseufert marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
public function __construct() | ||
{ | ||
$this->utcTimeZone = new \DateTimeZone('UTC'); | ||
} | ||
|
||
public function now(): \DateTimeImmutable | ||
{ | ||
return new \DateTimeImmutable('now', $this->utcTimeZone); | ||
} | ||
} | ||
|
||
// | ||
|
||
final class FrozenClock implements \Psr\Clock\ClockInterface | ||
{ | ||
private \DateTimeImmutable $now; | ||
|
||
public function __construct(\DateTimeImmutable $now) | ||
{ | ||
$this->now = $now; | ||
} | ||
|
||
public function now(): \DateTimeImmutable | ||
{ | ||
return clone $this->now; | ||
} | ||
|
||
public function advance(DateInterval $interval): void | ||
{ | ||
$this->now = $this->now->add($interval); | ||
} | ||
} | ||
|
||
``` | ||
|
||
## 5. People | ||
|
||
### 5.1 Editor | ||
|
||
* Chris Seufert | ||
|
||
### 5.2 Sponsor | ||
|
||
* Chuck Burgess | ||
|
||
### 5.3 Working group members | ||
|
||
* Luís Cobucci | ||
* Pol Dellaiera | ||
* Ben Edmunds | ||
* Jérôme Gamez | ||
* Andreas Heigl | ||
* Andreas Möller | ||
|
||
## 6. Votes | ||
|
||
* [Entrance Vote](https://groups.google.com/g/php-fig/c/hIKqd0an-GI) | ||
|
||
## 7. Relevant Links | ||
|
||
* https://github.com/ergebnis/clock/blob/main/src/Clock.php | ||
* https://github.com/icecave/chrono/blob/master/src/Clock/ClockInterface.php | ||
* https://github.com/Kdyby/DateTimeProvider/blob/master/src/DateTimeProviderInterface.php | ||
* https://github.com/kreait/clock-php/blob/main/src/Clock.php | ||
* https://github.com/lcobucci/clock/blob/2.1.x/src/Clock.php | ||
* https://github.com/mangoweb-backend/clock/blob/master/src/Clock.php | ||
* https://martinfowler.com/bliki/ClockWrapper.html | ||
|
||
## 8. Past contributors | ||
|
||
This document stems from the work of many people in previous years, we recognize their effort: | ||
|
||
* | ||
_**Note:** Order descending chronologically._ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
Common Interface for Accessing the Clock | ||
======================================== | ||
|
||
This document describes a simple interface for reading the system clock. | ||
|
||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", | ||
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be | ||
interpreted as described in [RFC 2119][]. | ||
|
||
The final implementations MAY decorate the objects with more | ||
functionality than the one proposed but they MUST implement the indicated | ||
interfaces/functionality first. | ||
|
||
[RFC 2119]: http://tools.ietf.org/html/rfc2119 | ||
|
||
# 1. Specification | ||
|
||
## 1.1 Introduction | ||
|
||
Creating a standard way of accessing the clock, would allow interopability | ||
during testing, when testing behavior that has timing based side affects. | ||
Common ways to get the current time include calling `\time()` or | ||
`new DateTimeImmutable('now')`. However, this makes mocking the current time | ||
impossible in some situations. | ||
|
||
## 1.2 Definitions | ||
|
||
* **Clock** - The clock is able to read the current time and date. | ||
|
||
* **Timestamp** - The current time as an integer number of seconds since | ||
Jan 1, 1970 00:00:00 UTC. | ||
|
||
### 1.3 Usage | ||
|
||
There are some common usage patterns, which are outlined below: | ||
|
||
**Get the current timestamp** | ||
|
||
This should be done by using the `getTimestamp()` method on the returned `\DateTimeImmutable` like so: | ||
```php | ||
$timestamp = $clock->now()->getTimestamp(); | ||
``` | ||
|
||
# 2. Interfaces | ||
|
||
## 2.1 ClockInterface | ||
|
||
The clock interface defines the most basic operations to read the current time and date from the clock. | ||
It MUST return the time as a `DateTimeImmutable`. | ||
|
||
~~~php | ||
<?php | ||
|
||
namespace Psr\Clock; | ||
|
||
interface ClockInterface | ||
cseufert marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
/** | ||
* Returns the current time as a DateTimeImmutable Object | ||
*/ | ||
public function now(): \DateTimeImmutable; | ||
cseufert marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
} | ||
~~~ |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure, do we need a trailing
;
or.
here? If so, perhaps consistently use one?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure, perhaps @ashnazg can weight in on this?