Lunar time for developers: how to timestamp lunar data
Key facts
- No lunar time scale has been realized, so there is no service to synchronize a device against today. [1]
- The JSON API on this site has two endpoints, /api/v1/now and /api/v1/drift, with no key and no quota. [1]
- Our model carries two rates: 56.02 µs/day for a lunar surface clock against an Earth geoid clock, and 58.7 µs/day for TCL against TT. [2]
- IAU 2024 Resolution II fixes the epoch: TCL reads 1977 January 1, 0h 0m 32.184s exactly when TCB reads the same value at the centre of the Moon. [3]Official
- LTE440 converts between Lunar Coordinate Time and the barycentric scales TCB and TDB, and exports the result in the SPICE format. [4]
There is no lunar time service to query. No scale has been realized, so nothing on the Moon or on Earth can tell you the lunar time the way an NTP server tells you UTC [1].
What you can do today is record UTC and carry the offset as a separate, sourced
quantity. This page sets out how, what our API returns, and what the
lunar-time package does.
Record UTC, carry the offset separately
Store the instant in UTC, exactly as you would for a measurement taken on Earth. Then store the model offset next to it, together with the rate you applied and the epoch you counted from [1].
A stored lunar reading without a rate and an epoch cannot be recomputed later. It is a number with no pair of scales attached, and it will be wrong the moment anyone revises the rate [2].
A record that survives a revision looks like this. The field names are yours; what matters is that all four values are present.
{
"observed_utc": "2026-08-23T00:00:00Z",
"model_offset_seconds": 1.015699,
"rate_us_per_day": 56.02,
"epoch_utc": "1977-01-01T00:00:00Z"
}
The offset in that record is a model value for a lunar surface clock against an Earth geoid clock: 18 131 days since the epoch at 56.02 µs/day is 1 015 698.62 µs [1]. It is a shape for your own storage, not the response of our API, which returns its own fields.
Task to action
Six things developers ask for, and what can honestly be done about each one today.
| Task | What to do today | Source |
|---|---|---|
| Timestamp an observation made on the Moon | Store UTC, plus the rate and epoch of the model offset you applied | [1] |
| Choose a rate constant | 56.02 µs/day for a lunar surface clock against an Earth geoid clock; 58.7 µs/day for TCL against TT | [2] |
| Choose an epoch | 1977 January 1, 0h 0m 32.184s, the epoch fixed for TCL by the IAU in 2024 | [3]Official |
| Convert TCL to TCB or TDB | Use LTE440, which exports the transformation in the SPICE format | [4] |
| Show a lunar reading in an interface | Print the word model, and name both scales next to the number | [5]Official |
| Synchronize a device to lunar time | Nothing: no scale has been realized, and the tie to UTC is not agreed | [6]Official |
The last row is the one that matters most. IAU Resolution III asks international organizations to agree the relations between a lunar reference time scale, a lunar coordinate time and UTC [6]Official. Until that is agreed, an offset written into your code is a guess.
What the JSON API gives you
Two endpoints live under /api/v1/, and the full contract is on
the JSON API page. Responses are JSON only, and there is no key and no
quota [1].
GET /api/v1/now returns the model offset at the moment of the request, for one
or both rate figures. GET /api/v1/drift returns the drift accumulated between
two moments you name, and a to earlier than from gives a negative result
rather than an error [1].
Every response carries three fields that cannot be switched off: disclaimer,
methodology and sources. If you display the number, display those as well.
Errors are JSON too, with a closed list of four codes, and the version sits in the path as well as in a field of every response. CORS is open, so a browser on any origin can call the endpoints directly.
What the lunar-time package gives you
The package is named lunar-time. It holds the same arithmetic that drives the
clock on this site, generated from the same file, so the package and the site
cannot drift apart [1].
Every function in it is pure. The instant is always an argument, nothing reads the system clock, and there are no dependencies. It is ESM only and needs Node 18 or newer.
It is not on the npm registry. Until it is published there, build it from the repository: the build writes a tarball, and a tarball installs from a path. This page carries no npm link, because there is no package at that registry to link to.
The package ships both rate constants and both epochs, so the choice stays explicit in your code rather than hidden in a default [2].
What none of this does
- It does not tell you the time on the Moon. Coordinated Lunar Time has been proposed and named, not realized [5]Official.
- It is not an ephemeris. No positions, no ranges, no light-time to a named station. For the conversion between coordinate times, use LTE440 [4].
- It models a constant rate. The periodic terms and the station altitude are left out, and every rounding is listed on the methodology page [1].
Before you put a microsecond figure in front of a user, read why microseconds matter: one microsecond of clock error is 299.79 m of light travel [1]. The software published on the other side of this subject is described in China and lunar time, and the Learn hub lists everything else.
Sources
- Our calculation: the lunartime.org clock model
- A Relativistic Framework to Estimate Clock Rates on the Moon
- Resolution to establish a standard Lunar Celestial Reference System (LCRS) and Lunar Coordinate Time (TCL)
- Lunar Time Ephemeris LTE440: User Manual
- Policy on Celestial Time Standardization
- Resolution on the establishment of a coordinated lunar time standard by international agreement
Last verified