Hi,

> On 7.10.2026 12:45 CEST Tim Düsterhus <[email protected]> wrote:
> 
>  
> Hi
> 
> On 2026-10-06 11:17, [email protected] wrote:
> > I think the following points still need some discussion. Some of
> > them may overlap with things others have already raised in this thread. 
> > Rather than replying to each of those messages separately, I've 
> > collected
> > everything in this one mail and mention who brought a point up where it
> > applies.
> 
> Thank you for the review. Derick and I already discussed some, but not 
> all of the points. For now I'll just reply to those that are resolved to 
> get them out of the way.
> 
> > 4. Configurable clock resolution
> > 
> > I'd like a way to configure the resolution,
> > e.g. a SystemClock that only ever returns whole seconds. Many consumers 
> > (JWT iat/exp, HTTP dates, database columns) never want fractions.
> > A clock configured that way guarantees whole seconds to every consumer 
> > it is injected into, instead of each consumer having to truncate on its 
> > own. It also makes test expectations simpler, because the values never 
> > carry
> > fractions.
> 
> We believe this is the job of a “Clock decorator”, e.g. `CoarseClock` 
> that takes in some clock and appropriately rounds or truncates the 
> Instant to the desired precision. Such a decorator would automatically 
> be compatible with any type of clock (e.g. a `FrozenClock` for testing).
> 
> As with the testing clocks, we consider a `CoarseClock` out of scope for 
> this RFC. With a possible future `truncateTo()` that I already mentioned 
> elsewhere in the discussion, a userland implementation would become 
> trivial for the use cases where a coarser clock is required.

Fine by me to keep it out of scope for this RFC. For a future RFC, though, I'd 
prefer a built-in CoarseSystemClock over a generic decorator. A decorator 
always has to read the precise clock first and only then truncates, so it can 
never be cheaper than the clock it wraps. A built-in system clock configured 
for second (or millisecond) resolution could read a coarse clock source 
directly instead, such as CLOCK_REALTIME_COARSE on Linux.

On Linux arm64 I measured:

  clock_gettime(CLOCK_REALTIME)          13.3 ns
  clock_gettime(CLOCK_REALTIME_COARSE)    3.3 ns

> 
> > 9. getNanoseconds()
> > 
> > It isn't obvious whether this returns the nanoseconds since epoch or 
> > the
> > nanoseconds within the current second. getNanoOfSecond() (Java's
> > NANO_OF_SECOND) would remove that ambiguity.
> 
> We believe that with the renaming of the “Unix timestamp” converter to 
> use the `to` prefix and the lack of “Unix” in the name of 
> `getNanoseconds()` the naming is clear enough. It is also easy to see 
> that the result of `getNanoseconds()` can't be the number of nanoseconds 
> elapsed since the Unix epoch, because the value is guaranteed to be less 
> than 1_000_000_000 (i.e. less than 1 second). Using `nanoseconds` as the 
> fractional part is consistent with `Duration::$nanoseconds`.

I'm not convinced yet

The value range is only "easy to see" after reading the documentation. The name 
alone should tell you what you get. Within the same class, the plural unit is 
used as a unit marker: toUnixTimestampMilliseconds() is "the timestamp in 
milliseconds". Read the same way, getNanoseconds() is "<something> in 
nanoseconds", and the only <something> an Instant has is its position on the 
timeline.

Duration is the wrong reference. A Duration is an amount, so "N nanoseconds" is 
correct there. An Instant is a point in time, and its sub-second part is a 
position within the second, not an amount. PEven the current DateTime* API 
already makes this distinction, using singular names:

     DateTime::getMicrosecond(): int
     DateTime::setMicrosecond(int $microsecond)
     DateTime::setTime(int $hour, int $minute, int $second = 0, int 
$microsecond = 0)

while the plural is used for amounts:

     Duration::fromMicroseconds(int $microseconds)
     Duration::fromMilliseconds(int $milliseconds)

getNanoOfSecond() removes the ambiguity entirely, at the cost of a few 
characters. If that's too far from the existing naming, getNanosecond() would 
at least match DateTime::getMicrosecond().

> 
> For completeness I'd like to note that the epoch of the Instant is 
> intentionally left unspecified and that the Unix epoch is just one of 
> several possible epochs.

Agreed, and that's exactly the point I made about "follows POSIX time": if
the epoch and the representation are unspecified, the class definition
shouldn't state that Instants follow POSIX time. That belongs to the Unix
timestamp conversion methods.

Best regards,
Marc

> 
> Best regards
> Tim Düsterhus

Reply via email to