Skip to content

feat: add ExtendedClientDetails.getBrowserTime() returning an Instant - #25480

Open
totally-not-ai[bot] wants to merge 3 commits into
mainfrom
9291-browser-time-instant
Open

feat: add ExtendedClientDetails.getBrowserTime() returning an Instant#25480
totally-not-ai[bot] wants to merge 3 commits into
mainfrom
9291-browser-time-instant

Conversation

@totally-not-ai

@totally-not-ai totally-not-ai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Adds ExtendedClientDetails.getBrowserTime(), which reports the estimated current time in the end user's browser as a java.time.Instant instead of the obsolete java.util.Date.

An Instant is a point on the time line, so the value no longer depends on the default time zone of the server JVM. Combining it with getTimeZoneId() gives the date and time as actually shown on the end user's computer.

What changed

  • New public Instant getBrowserTime() on ExtendedClientDetails, computed from the existing client/server time delta.
  • getCurrentDate() is deprecated for removal (@Deprecated(since = "25.3", forRemoval = true)) and now delegates to getBrowserTime(), so its behaviour is unchanged for existing callers.
  • The Javadoc documents that getTimeZoneId() may return null when the browser did not report a time zone, and shows the fallback needed when converting to a ZonedDateTime.
  • Unit test covering a browser clock that runs ahead of the server, asserting both the new method and that the deprecated getCurrentDate() still agrees with it.
  • The InitialExtendedClientDetails view and IT now exercise getBrowserTime() instead of getCurrentDate().

Test fix (first commit)

The existing three-argument assertEquals(...) call in ExtendedClientDetailsTest bound to the float overload, where one ulp at epoch-milli magnitude is roughly 131 seconds — making the intended 1000 ms tolerance meaningless. The assertion now compares with Math.abs(...) against an explicit TIME_TOLERANCE_MS constant.

Use case

An application shows an audit log and wants each entry timestamped the way the user experienced it — a support agent in Helsinki looking at a log written from a browser in New York should see the New York wall-clock time, not the server's. Reading the browser clock as an Instant plus the reported zone gives exactly that, without the result silently shifting depending on which time zone the server JVM happens to run in.

@Route("audit")
public class AuditView extends Div {

    public AuditView() {
        ExtendedClientDetails details = UI.getCurrent().getPage()
                .getExtendedClientDetails();

        String timeZoneId = details.getTimeZoneId();
        ZoneId zone = timeZoneId != null ? ZoneId.of(timeZoneId)
                : ZoneId.systemDefault();

        ZonedDateTime shownToUser = details.getBrowserTime().atZone(zone);

        // Store the absolute instant, plus how the user saw it locally
        auditLog.record(new AuditEntry(details.getBrowserTime(), zone));

        add(new Span("Recorded at " + shownToUser
                .format(DateTimeFormatter.RFC_1123_DATE_TIME)));
    }
}

API Changes

com.vaadin.flow.component.page.ExtendedClientDetails

// Added
public Instant getBrowserTime() // estimated current browser time as a time-zone independent Instant, never null

// Changed
- public Date getCurrentDate()
+ @Deprecated(since = "25.3", forRemoval = true) public Date getCurrentDate() // deprecated for removal in favour of getBrowserTime(); behaviour unchanged, now delegates to it

…9291

Adds getBrowserTime(), which reports the estimated current time in the
browser as a java.time.Instant instead of the obsolete java.util.Date.
The value is a point on the time line, so it no longer depends on the
default time zone of the server; combining it with getTimeZoneId() gives
the date and time as shown on the end user's computer.

getCurrentDate() is deprecated for removal and now delegates to the new
method, so its behaviour is unchanged.
The three-long assertEquals(...) call bound to the float overload, where
one ulp at epoch-milli magnitude is about 131 seconds, so the 1000 ms
tolerance was meaningless. Compare with Math.abs instead, and document
in getBrowserTime() that getTimeZoneId() may be null.
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Test Results

 1 434 files  ±0   1 518 suites  ±0   1h 37m 29s ⏱️ - 25m 3s
11 866 tests +1  11 799 ✅ +1  67 💤 ±0  0 ❌ ±0 
12 185 runs  +1  12 117 ✅ +1  68 💤 ±0  0 ❌ ±0 

Results for commit 5bea650. ± Comparison against base commit 3b704d9.

♻️ This comment has been updated with latest results.

@github-actions github-actions Bot added the +0.1.0 label Sep 4, 2026
@sonarqubecloud

sonarqubecloud Bot commented Sep 4, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant