CreepJS Timezone Report: Offsets and Location
Separate CreepJS timezone fields, historical offset comparisons and conditional display from physical location, identity and an automation verdict.
BotBrowser Team
Want the structured docs for Fingerprint?
This article lives in the editorial library. For step-by-step setup, reference material, and ongoing updates, jump into the docs section.
A CreepJS timezone report combines a timezone identifier, date text, historical calculations and current-date offsets. Its locationMeasured name does not mean that a location sensor measured the visitor. BotBrowser supports timezone, locale and language configuration, but it does not guarantee a CreepJS classification or make timezone output establish physical location. Each field needs its own input and comparison context before a report difference can explain a browser inconsistency.
TL;DR
locationcomes from the default formatter's timezone identifier;zonecomes from a parenthesized part of a Date string.locationMeasuredfollows a fixed historical comparison and a fixed city list. It is not geographic coordinates or an exhaustive list of compatible zones.- The historical comparison uses
1113;offsetandoffsetComputeduse separate current-date paths. Those are not one measurement repeated three times. - The renderer shows one selected location value and one selected offset value, hiding the corresponding alternative when they differ.
liedinherits existing method concerns. A missing report, a changed display label and an inherited concern are different states.
Contents
- Seven fields with different producers
- Historical offsets and a bounded candidate search
- Two current-date offset paths
- Display selection and inherited concerns
- Comparison cases and useful records
- FAQ: timezone report boundaries
- Practical conclusion
Seven fields with different producers
The pinned CreepJS timezone module at revision 10aa6724cd33a1015db1574211890518cd04f0cc returns seven named properties. Their provenance matters more than their proximity in a card. A timezone identifier describes a ruleset selected by a runtime; a numeric offset describes a relationship for a date; a timestamp describes an instant produced by date construction. Converting all three into a single “location” answer discards the distinction that makes a disagreement diagnosable.
The location field starts with Intl.DateTimeFormat().resolvedOptions().timeZone. No explicit timezone is supplied to that formatter. The field therefore reflects the runtime's default selection rather than a request to locate the user. The module then applies presentation changes to the identifier: it replaces one underscore with a space and turns slashes into comma separators. A displayed location label is consequently not the untouched identifier string. Preserve the original identifier separately when a comparison concerns spelling or aliases.
The zone field uses a different producer. It converts a fresh Date to text and extracts the portion selected by a parenthesis-removal expression. That is not a second call to resolvedOptions(). Date text and an IANA timezone identifier can have different names and purposes without contradicting one another. A human-readable zone description should not be substituted for the identifier expected by an application's timeZone option.
| Field | Producer in the pinned module | Maximum supported interpretation |
|---|---|---|
zone | Text selected from a fresh Date string | A display description from that string |
location | Default formatter timezone, then presentation formatting | A reported timezone identifier shown as a label |
locationMeasured | Historical comparison and conditional candidate summary | A result of that source-defined comparison |
locationEpoch | Numeric conversion of a local historical date | A constructed historical timestamp |
offset | A fresh Date's getTimezoneOffset() | Offset for the date represented by that instance |
offsetComputed | Difference between two separately parsed date strings | A current-date calculation with different construction rules |
lied | First truthy value among existing concern entries, otherwise false | An inherited assessment, not a new location measurement |
The CreepJS Intl report analysis separates formatted samples from constructor-locale collection. The timezone card requires a similar provenance distinction, but its producers are not the Intl collector's six formatting callbacks. A date label appearing beside a timezone field does not make those modules interchangeable. Source revision, returned property and rendered line belong in the same comparison record so that values from different collectors are not silently paired.
locationEpoch is especially easy to misread as collection time. The source constructs a date using July 1 in 1113 and converts it to a number. That number is not supplied by a consented location API and does not record when the report page was opened. A support system that stores it in a “last seen” column would introduce an error in its own data model, even if the displayed number exactly matched the detector's output.
Historical offsets and a bounded candidate search
The historical path compares two calculations for the same selected year. One follows the system's local date construction; the other involves an explicit timezone through Intl.DateTimeFormat. The source chooses 1113 and a July date. It does not compare today's offset directly against a historical offset and declare equality to be a geographic match. The current fields offset and offsetComputed are assembled separately later in the collector.
When the two historical results agree, the candidate reduction starts with the reported timezone itself. Otherwise, the module searches its bundled cities list for entries whose historical calculation equals the system result. This is a source-defined collection of timezone names, not a live geographic directory. Its membership is part of the pinned revision. A timezone absent from that list cannot become a discovered candidate merely because the runtime recognizes its identifier.
The recursive helper also limits what “matching set” can mean. It filters the left part of a list and returns a matching subset when one is found; it recurses into the right part only when that left result is empty. It does not concatenate every match from both halves into a global result. Describing its output as all timezones consistent with an observation would therefore be stronger than the inspected search supports. The list and search strategy both constrain the resulting subset.
The last reduction preserves a name only when the subset has one member and that member equals the reported timezone. Other outcomes are passed through the project's compact summary helper. A compact value in locationMeasured is not a city name that the browser discovered but refused to reveal. Nor does equality between two summaries prove equal complete timezone databases. The original membership and search context are information that the display summary does not expose.
IANA's timezone theory documentation explains why historical data requires additional restraint. Its principal compatibility scope concerns clocks that agree after 1970, while earlier records can be incomplete and geographically limited. A date in 1113 is useful for examining how two software paths interact with their historical rules; it is not an independently validated record of a visitor's medieval location. An observed difference would need browser, runtime-data and date-construction context before it could be attributed to a particular cause.
Names, rules and geography
Timezone identifiers designate rule histories associated with representative locations. They do not function as a current GPS fix. Several places can share an offset at a given instant, and a person can select a timezone unrelated to their present location. The ICU alias and timezone comparison addresses reported names and fixed-offset comparisons in a separate recorded environment. Its outputs should not be imported as measurements of this pinned CreepJS module.
The source-derived boundary remains useful even without running a browser. A locationMeasured value can be classified as a preserved reported name or a compact candidate result. That classification identifies which comparison branch produced the value; it does not certify a country, network route or person. Any claim about coordinates requires evidence from a location-producing interface and its permission context, neither of which is an input to this timezone collector.
Two current-date offset paths
The direct offset field reads new Date().getTimezoneOffset(). MDN defines its result in minutes, with positive values when the local timezone is behind UTC and negative values when it is ahead. The date represented by the instance matters because daylight-saving and historical rules can change the offset across dates. An offset should therefore remain attached to the instant or date used to obtain it rather than being stored as a permanent property of a timezone name.
The offsetComputed helper starts elsewhere. It extracts the date portion of a newly serialized ISO date, constructs two date strings using different forms, subtracts their numeric date values and converts the difference to minutes. The ISO date portion follows UTC's calendar day. It need not equal the host's local calendar day near midnight. This helper does not simply call the direct offset method again, and its selected date construction is relevant to comparisons around clock transitions.
One constructed form is an ISO date-only string; the other uses slash-separated month, day and year. ECMA-262 specifies the date-only form's UTC interpretation. MDN notes that parsing nonstandard forms can vary by implementation. A source explanation can name those input forms, but a claim that all browsers parse the slash form identically would require evidence beyond the standard date-time string rules. The computed result should not be promoted to an independent reference clock.
The helper applies ~~ to its minute difference. That operator performs an integer conversion; it does not record the original milliseconds or attach an exception category to a result. Numeric agreement after conversion is weaker than a comparison of the complete intermediate inputs. When a report preserves only its final offset line, those construction details cannot be recovered by reading the number more precisely or adding a timezone abbreviation beside it.
Transition-sensitive comparisons
A hypothetical report collected near a daylight-saving transition illustrates the input problem. The fresh Date used by offset and the calendar-based strings used by offsetComputed do not necessarily represent the same instant. A difference can therefore require checking date selection before investigating an API modification. This is an interpretation case, not an observed browser result. No particular transition outcome is established by reading the collector's source alone.
The comparison record can resolve the ambiguity without storing an entire fingerprint. Preserve the capture time, timezone identifier, raw values of both offset fields and the source revision. If the question depends on a transition, retain the exact dates that were constructed. An offset without its date cannot establish which daylight-saving rule applied, while two numbers shown as one renderer-selected line cannot establish that the producer paths agreed.
Display selection and inherited concerns
The normal renderer does not print a labeled pair for every comparison. For location, it chooses locationMeasured when the two location values differ, otherwise location. For offset, it chooses offsetComputed when the two offset values differ, otherwise offset. A screenshot of the card can consequently omit the alternative value precisely when a difference exists. Inferring agreement because only one number is visible reverses what that conditional display establishes.
The normal card also shows zone when it is truthy and prints locationEpoch. These display choices explain the provenance of each line, but they do not turn line order into a complete diagnostic record. An absent label is not automatically a failed timezone API. A rendered value and its underlying object have different information content, so a comparison intended to diagnose a mismatch should retain the named raw fields rather than only the card's visual ordering.
The lied property is assembled from three previously populated concern keys using JavaScript's || operator, falling back to false. This preserves the first truthy operand; it is not a count of three findings. More importantly, the timezone collector does not set that property by testing whether offset equals offsetComputed or whether the displayed location string resembles a city. An inherited concern and a local field difference must remain separate observations.
If the outer collection block throws, the module records a failed collection, captures the error and returns no report object. The renderer checks for an absent fp.timezone and selects its blocked annotation. The annotation alone does not identify which constructor, parse, property access or historical operation failed. A support explanation that names one failed API from that label would be guessing past the available evidence.
| Visible situation | Additional field needed | Conclusion available without it |
|---|---|---|
| One offset line is visible | Both offset and offsetComputed | The renderer selected a value; agreement is unknown |
| A compact location value appears | location, locationMeasured and revision | A source-defined summary is displayed, not coordinates |
| The card has concern styling | Originating concern entry | An inherited assessment affected display |
| A blocked card appears | Collector presence and captured error context | The normal report object was unavailable to that branch |
Comparison cases and useful records
A changed zone description with an unchanged identifier is a text-layer comparison. It should be investigated as a difference between Date text and the recorded location producer, rather than as evidence that two devices occupy different regions. A changed timezone identifier instead concerns formatter resolution and configuration. Those cases have different next checks even if both are described informally as a “timezone changed” report.
A preserved location paired with a changed locationMeasured concerns the historical comparison or its fixed-list reduction. The first comparison inputs are the CreepJS revision and runtime timezone data, not a new claim about a visitor moving. A changed locationEpoch concerns the constructed historical date as well. Keeping these properties separate prevents a support system from translating a software-data difference into an unjustified real-world travel event.
A changed offset with stable timezone naming can be compatible with date-dependent rules. The record needs the dates before it can distinguish a daylight-saving change from a configuration change. Conversely, a matching offset does not establish a matching timezone ruleset: one instant cannot describe every historical or future transition. The useful comparison is a named field under specified inputs, not a general assertion that two environments have the same identity.
BotBrowser's timezone documentation describes automatic defaults and explicit overrides alongside separate locale and language controls. Those documented settings provide configuration context; they do not certify the collector's historical calculation or an external site's interpretation. A report investigation should first establish which setting was intended and which value was actually reported. Changing a configuration solely to remove a detector label would substitute a desired appearance for an explanation of the original difference.
For a bounded support record, retain the tool revision, capture date, browser build, intended timezone setting and the named fields relevant to the question. Record absence as absence, and distinguish a missing object from a missing display description. Raw combined fingerprints and unrelated browsing data are unnecessary for explaining which branch produced a timezone line. If an error is available, preserve a redacted category that identifies the failed operation without collecting unrelated page content.
FAQ: timezone report boundaries
Does locationMeasured use the browser's geolocation permission?
The pinned producer follows historical Date and Intl calculations plus its city list. That path does not request geographic coordinates. Its field name is not evidence of a location permission prompt, GPS observation or current country.
Is locationEpoch the time when the report was collected?
No. It comes from the local historical July date constructed with 1113. Capture time belongs in a separate record. Reusing the historical timestamp as a report timestamp would change the meaning of the value.
Does a matching current offset validate the historical comparison?
No. offset and offsetComputed use current-date paths, while the candidate path uses the selected historical year. Agreement in one comparison does not prove agreement under the other inputs or across a complete timezone history.
Why might a screenshot contain only one offset despite a mismatch?
The renderer selects offsetComputed when it differs from offset. It does not print both with separate labels. The raw object is required to distinguish equality from this mismatch-selection branch.
Does lied count timezone mismatches?
The inspected collector inherits the first truthy concern value from three method entries. It does not calculate a mismatch count from the displayed location or offset lines. The concern's origin is separate evidence.
Can BotBrowser configuration prove a visitor's physical location?
Timezone, locale and language controls describe browser configuration. They do not establish a person's coordinates or guarantee a detector's classification. A reported timezone and a physical-location measurement answer different questions.
Sources
- CreepJS: pinned timezone collector and renderer
- CreepJS: pinned summary helpers
- CreepJS: pinned error helpers
- MDN: Date.getTimezoneOffset
- MDN: Date.parse and nonstandard inputs
- MDN: DateTimeFormat.resolvedOptions
- ECMA-262: numbers and dates
- IANA: timezone database theory
- BotBrowser: timezone, locale and language settings
Practical conclusion
A timezone report is useful when its fields retain their producers and dates. Separate the resolved identifier and Date text from the historical candidate path and the two current-date offsets. Inspect both raw alternatives behind a renderer-selected line, and trace an inherited concern before assigning a failure cause. Those distinctions support a concrete inconsistency investigation without converting timezone output into physical location, personal identity or a third-party automation verdict.
This article is part of the guide: What Is a Browser Fingerprint?
Related Articles
CreepJS Intl Report: Fields and Missing Values
IdentityTimezone, Locale, and Language in Browser APIs
FingerprintICU Timezone Aliases and the TZ You Actually Report
FingerprintCreepJS WebGL Report: Contexts and Capability Signals
FingerprintCreepJS Math Signals: Read the Source Fields
FingerprintCreepJS Android WebView Detection: Signal Limits
Take BotBrowser from research to production
The guides cover the model first, then move into cross-platform validation, isolated contexts, and scale-ready browser deployment.