Time Stamps and Clocks

UTC and ISO 8601, clock drift in ppm, NTP, PTP and GPS, jitter, stamping at the source and synchronizing several loggers.

What a time stamp must be

A data point is a value and a time. Most analysis (rates, delays, correlations between channels, alarms, reports for an audit) depends on the time being right, unambiguous and ordered. A good time stamp is:

  • Unambiguous: the time zone and the date are explicit, with no daylight-saving gap or overlap.
  • Monotonic when it needs to be: never goes backwards; if the wall clock is corrected, the log should show it, not corrupt the order.
  • Accurate to what you need: a second for a building log, a millisecond for a machine, a microsecond for fast synchronous channels.
  • Traceable: you can tell which clock supplied it and when it was last synchronized.
  • Taken at the right moment: when the sample was acquired, not when it was processed, transmitted or written.

UTC and ISO 8601

Store UTC and write it in ISO 8601: 2026-10-31T10:40:00Z (year, month, day, T, hour, minute, second, Z for UTC). It sorts correctly as text, has no ambiguity between day and month, and has no daylight-saving shift. Convert to local time only when displaying.

FormatExampleRemarks
ISO 8601 with Z2026-10-31T10:40:00ZBest for files and databases. Add fractions for sub-second: 12:00:00.250Z
ISO 8601 with offset2026-10-31T03:40:00-07:00Clear if you must show local time; the offset is kept with the value
Unix time (seconds)1 793 443 200Seconds since 1970-01-01 UTC. Compact and easy to subtract; add milliseconds as a decimal or in a separate column
Excel date serialdays since 1899-12-30Convenient in a spreadsheet; loses the zone and precision. Convert on import, do not store as primary
“10/31/26 3:40 PM”(ambiguous)Which month? Which zone? 12- or 24-hour? Avoid in data

Worked example: Unix time

  • Unix time 1 793 443 200 is 20 757 whole days after 1970-01-01, and is 2026-10-31T10:40:00Z.
  • The 2038 problem. A signed 32-bit seconds counter overflows at 2 147 483 647, which is 2038-01-19 03:14:07 UTC. Use 64-bit time in new designs.
  • Leap seconds. UTC occasionally adds a second; Unix time ignores it, and GPS time (no leap seconds) is currently 18 s ahead of UTC. For logs that need sub-second continuity use a smoothed clock (“leap smear”) or a monotonic counter beside UTC.

Clock drift

Every clock runs a little fast or slow, measured in parts per million (ppm). One ppm is 1 µs of error per second, or 0.0864 s per day. Drift also changes with temperature, so a clock that is right in the lab may be wrong on a roof.

error (s per day) = ppm × 0.0864

ClockTypical errorPer dayPer 30 days
Uncompensated 32.768 kHz crystal (typical)20.0 ppm1.73 s51.84 s
Cheap RTC module (DS1307-class)50.0 ppm4.32 s2.2 min
Temperature-compensated RTC (DS3231)2.0 ppm0.17 s5.18 s
TCXO0.5 ppm0.04 s1.30 s
Microcontroller internal RC oscillator10000.0 ppm14.4 min432.0 min
Clock drift grows in proportion to time060120180240300365051015202530daysclock error (minutes)1 ppm: 0.5 min a year5 ppm: 2.6 min a year20 ppm: 10.5 min a year50 ppm: 26.3 min a year
Accumulated clock error against time for different crystal qualities.

Worked example: a 20 ppm RTC

  • A 20 ppm clock is off by 20 × 0.0864 = 1.73 s per day, so it is a full second out after 0.6 days and a minute out after 35 days.
  • How often to re-sync? To stay within 1.0 s with a 2 ppm clock, correct it at least every 5.8 days; with the 20 ppm clock, every 0.6 days.
  • Two loggers with opposite 20 ppm errors differ by 40 ppm: 3.46 s per day. Comparing events between them without synchronization is meaningless at the second level after a week.
  • A microcontroller’s internal RC oscillator can be 1 % (10 000 ppm) off, which is 14 minutes a day: never use it as a time base for a log without a crystal or a sync source.

Time sources: RTC, NTP, PTP and GPS

SourceTypical accuracyNeedsBest for
Battery-backed RTC (DS3231, PCF8523)2 to 20 ppm; seconds per monthA coin cell; set once; I²CStandalone loggers without a network
NTP (Network Time Protocol)About 1 to 50 ms over the internet; less than 1 ms on a good LANA network; a time serverMost networked loggers, PCs, Raspberry Pi
SNTP (simple NTP)Tens of ms; one-shot correctionsA small client in a microcontrollerESP32 and similar, set the RTC at boot and daily
GPS / GNSSAbout 50 ns to 1 µs with the 1PPS pulse; 100 ms withoutAn antenna with sky viewRemote sites, no network, many synchronized loggers
PTP (IEEE 1588)Under 1 µs; sub-µs with hardware stampingPTP-capable switches and NICs, a grandmasterSynchronized industrial and test systems
Radio time signals (WWVB, DCF77)About 10 ms plus propagationA low-frequency receiverCheap clocks that correct themselves
Cellular network time (NITZ)About 1 sA modemCoarse setting of remote loggers
  • Set the clock, then discipline it. A one-time set at startup is not enough; correct drift regularly, and gently (slew the clock rather than jumping it) so that timestamps stay monotonic.
  • Record the sync state: the source, the last sync time and the estimated error, in the data or its metadata (see Planning a Logging System).
  • Without a network, check against the truth: note the logger’s time against a reference when you visit; the offset divided by the days gives the ppm, and you can correct the whole record afterwards.
  • Linux: chrony or systemd-timesyncd for NTP; a Raspberry Pi has no RTC by default, so add one or the time restarts from the last saved value after a power cut.

Where to stamp the data

The time should be captured as close to the measurement as possible. Each stage between the sensor and the file adds delay that varies:

Stamp applied at…Delay and uncertaintyUse when
The ADC or hardware timer (interrupt or DMA)Microseconds, fixedFast or synchronized channels
The logger firmware, when it reads the sensorHundreds of µs to a few ms, depending on the loopMost loggers
A gateway, when the message arrivesNetwork latency, such as 80 ms and variable; much more after an outageSlow trends only; never after buffering
The database, when it is insertedSeconds to hours after a buffering outageNever as the only time

Worked example: why stamping on arrival fails

A remote logger sends a reading every second, and buffers while the network is down. If the server stamps readings when they arrive, 600 readings held for a 10-minute outage all get the same minute, and the real order and spacing are lost. Stamp at the logger, send the stamp with the value, and keep the server’s receipt time as a separate field to measure delay.

  • Send both times: the device time (t_sample) and the receipt time (t_received); their difference is a free health check.
  • Keep a sample counter beside the time: missing counts reveal lost samples, even if the clock jumped.

Jitter and regular sampling

Jitter is the variation in the interval between samples. A hardware timer starting each conversion gives a few nanoseconds; a software loop with sleep(0.001) on a general-purpose operating system can wander by milliseconds, and an occasional stall of tens of ms.

Worked example: software timing at 1 kHz

Sampling at 1 000 Hz means a 1 ms interval. A 5 % jitter is 50 µs. For a signal at 100 Hz the worst amplitude error is 2π f Δt = 2π × 100 × 0.00 ≈ 3.14 %, which is acceptable; at 5 kHz the same jitter would be 157.1 %: not acceptable. Use a hardware timer for fast sampling.

  • Drive the ADC from a timer, read the results in an interrupt or by DMA, and stamp them from the timer count (see Embedded Systems).
  • Use absolute scheduling, not sleep(interval): set the next wake-up as t0 + n × interval, so errors do not accumulate.
  • Do not use the wall clock to measure intervals; it can step when the time is corrected. Use a monotonic clock (time.monotonic(), millis()) and convert to UTC at the end.

Synchronizing several loggers

NeedMethod
SecondsNTP on all units, or the same RTC set from one reference
MillisecondsNTP on a local server over wired Ethernet, or a shared GPS receiver
MicrosecondsPTP with hardware stamping, or a GPS 1PPS pulse wired to every logger
Simultaneous samplesOne converter, or a shared sample clock (and trigger) to all converters
Events onlyA shared marker: a pulse, a flash, a tap, recorded on every channel; align the data to it afterwards
  • Start together: a common start trigger plus a common clock removes the need to correct later.
  • Use a marker even when synchronized: a recorded event in every log lets you verify the alignment, and fix it in the analysis.
  • Convert to a common axis (seconds since the marker, or UTC) before joining logs from different sources (see Data, Files and Parsing).

Time zones, daylight saving and rollovers

ProblemWhat happensPrevention
Daylight-saving changeIn autumn a local hour occurs twice (two different readings share a stamp); in spring one hour is missingStore UTC; show local time only
Time zone not recordedA log from another site cannot be placed in timeStore the offset or use UTC, and note the site zone
Clock set wrongly after a power cutA logger without an RTC restarts at 2000-01-01 or 1970-01-01Battery-backed RTC; flag data written before a first sync
Millisecond counter rolloverA 32-bit millis() wraps after 49.7 days, and a microsecond counter after 1.2 hoursSubtract with unsigned arithmetic, or keep a 64-bit counter; log the wrap
Time stepped backwardsA sync corrects the clock by seconds; samples appear out of orderSlew, do not step; keep a sample counter; sort on the counter
Spreadsheet date manglingExcel drops fractions of seconds or reads dates in a local formatKeep the primary data in ISO 8601 text or Unix time

Related

FAQ

Which time zone should my log use?

UTC in ISO 8601 with a Z (or an explicit offset). Convert to local time only for display. It avoids daylight-saving ambiguity and makes logs from different places comparable.

How accurate is NTP?

About 1 to 50 ms over the internet and under 1 ms on a good local network; enough for most logging. For microseconds use PTP or GPS.

My logger loses a few seconds a month. Is it faulty?

Probably not: a 2 to 20 ppm crystal drifts 5 to 50 seconds a month. Add periodic synchronization, or a temperature-compensated RTC.

Should I stamp the data on the device or on the server?

On the device, at the time of the measurement, and also record the server’s receipt time. A server stamp alone is wrong after any buffering or outage.

References

  • ISO 8601-1:2019, Date and time: representations for information interchange; RFC 3339 (internet profile).
  • RFC 5905 (NTP version 4); IEEE 1588-2019 (PTP); the chrony and ntp.org documentation.
  • Mills, D. L., Computer Network Time Synchronization; RTC datasheets (Maxim DS3231, NXP PCF8523).

Last reviewed: October 2026. Clock accuracies are typical; check your hardware’s datasheet and measure the real drift over time.