Automation Glossary • Normalize Timestamps in a Historian

How to Normalize Timestamps in a Historian

Merobix Engineering • • 8 min read

Data from a dozen devices only tells a coherent story if every timestamp means the same thing, and that is exactly where historians quietly go wrong - mixed time zones, a daylight-saving jump, receipt times masquerading as event times. This guide is for the engineer setting up how a historian records and interprets time, so events from different sources line up correctly and a query returns the same answer no matter who runs it or when.

Back to Blog

Normalize Timestamps in a Historian in one line: To normalize timestamps in a historian, store all times in a single absolute reference - UTC is the standard choice - so data from different devices and time zones lines up, keep the source timestamp (when the event happened) rather than the receipt timestamp (when it arrived) wherever the source provides one, and handle daylight-saving transitions and late-arriving data by their real event time. Convert to local time only for display, never for storage.

Store in One Absolute Reference

The foundation of timestamp normalization is storing every time in one absolute reference, and UTC is the conventional choice because it does not shift with time zones or daylight saving. When the historian stores UTC, data from a device in one location and a device in another line up correctly on a single timeline, and a query returns a consistent answer regardless of where it is run. Storing local time instead means every query has to know and correct for the zone and the season, which is where inconsistency creeps in.

Convert to local time only at the moment of display, never in storage. An operator reading a trend wants local time, so the presentation layer converts UTC to local for the screen - but the stored value stays UTC. This separation of storage from display is the whole trick: one canonical stored time, converted on the way out for humans, so the underlying data is unambiguous while the display is still readable. Baking local time into storage is what makes a historian's timeline fragile.

Make the reference consistent with the rest of the stack. The clocks feeding the historian must agree with the reference the historian stores against, or the normalization is applied to already-inconsistent data. This is why timestamp normalization sits on top of clock synchronization - normalizing the format cannot fix clocks that disagree, so it depends on time sync across the stack being sound first, then handles the representation cleanly on top.

Keep Source Time and Handle Late Data

Preserve the source timestamp over the receipt timestamp wherever the device provides one. When an event happened at the RTU carries a different meaning from when the master received it, and normalizing to receipt time silently reorders events that transited at different speeds or were buffered. Where a device timestamps its own events, keep that source time through to the historian, because the source time is what actually reflects the sequence of the process. Confusing the two is the same error that breaks event ordering across devices.

File late-arriving data by its real event time, not its arrival time. When a store-and-forward buffer or a backfill delivers old data after an outage, each record must land at the timestamp it actually happened, so the recovered history slots correctly into the timeline rather than bunching at the moment it arrived. A historian that keys everything off arrival time turns an outage recovery into a wall of events at the reconnect instant, destroying the timeline the recovery was supposed to restore. This is the timeline half of store-and-forward buffering.

Decide how the historian handles a record that arrives for a time it has already stored. Late data may fill a gap, or it may correct or duplicate an existing sample, and the historian needs a defined rule for each case so recovery does not create duplicates or overwrite good data. Handling this correctly is what makes a late historian backfill land cleanly, filing each record at its event time without disturbing what was already there.

Handle Daylight Saving and Zone Boundaries

Daylight-saving transitions are where local-time storage breaks visibly, and UTC storage avoids the whole problem. In the spring-forward, an hour of local time never exists; in the fall-back, an hour repeats, so a locally-stamped historian either has a gap or two records claiming the same local time. Because UTC has no daylight saving, storing UTC makes both transitions ordinary continuous time, and the ambiguity only has to be resolved once, at display, where the presentation layer applies the correct offset for the date.

Get the display conversion right across the transition, because that is the only place the complexity remains. A trend spanning a daylight-saving change should render each point at its correct local time, which means the display logic applies the offset that was in effect at each point's actual date, not a single current offset across the whole span. Done right, the operator sees continuous local time with the hour handled correctly; done wrong, the trend shows a phantom gap or overlap that the underlying UTC data does not actually have.

Label times with their reference so no one misreads them. A timestamp shown without indicating whether it is UTC or local, and which zone, invites exactly the misinterpretation normalization exists to prevent, particularly when data crosses between systems or people in different locations. Making the reference explicit - on displays, in exports, in reports - keeps a normalized timeline from being un-normalized by a reader who assumes the wrong zone, which matters whenever data leaves the historian for a historian export over ODBC or a report.

Verifying Timestamps Line Up

Test normalization by comparing events across devices and across a daylight-saving boundary. Cause two events on two devices whose true order you know and confirm the historian records them in that order, proving source time and the common reference work together. Then look at a trend spanning a daylight-saving transition and confirm it is continuous, with no phantom gap or repeated hour, which proves the UTC storage and display conversion are handling the transition correctly rather than exposing it.

Exercise late-arriving data specifically. Force an outage recovery or a backfill of old data and confirm the recovered records land at their real event times, integrated into the timeline where they belong, not bunched at the arrival moment and not duplicating or overwriting existing samples. This is the test that catches a historian keying off receipt time, and it belongs in your configuration validation because a timeline that looks fine in normal operation can still collapse the first time it has to absorb recovered data.

Common Mistakes to Avoid

The root mistake is storing local time instead of an absolute reference, which forces every query to correct for zone and season and breaks visibly at daylight-saving transitions. Store UTC and convert to local only for display. The second mistake is normalizing to receipt time when a source time exists, which silently reorders events that were buffered or transited at different speeds, corrupting the very sequence the timestamps are meant to establish.

The third mistake is filing late-arriving data by arrival time, so an outage recovery bunches old events at the reconnect instant and destroys the timeline. File by real event time. The fourth is showing timestamps without labeling their reference, so a reader in another zone misinterprets a normalized time and un-normalizes it in their head - make the reference explicit on every display, export, and report.

Frequently Asked Questions

Should a historian store timestamps in UTC or local time?

UTC, because it does not shift with time zones or daylight saving, so data from devices in different locations lines up on one timeline and a query returns the same answer regardless of where it runs. Convert to local time only at display, never in storage. Storing local time forces every query to correct for zone and season and breaks visibly at daylight-saving transitions, where an hour either vanishes or repeats.

Why do daylight-saving changes break historian timestamps?

Because in a locally-stamped historian the spring-forward creates an hour of local time that never existed, leaving a gap, and the fall-back repeats an hour, leaving two records claiming the same local time. Storing UTC avoids the problem entirely since UTC has no daylight saving, making both transitions ordinary continuous time. The ambiguity then only has to be resolved once, at display, where the correct offset for each point's date is applied.

How should a historian handle late-arriving data?

File each record by its real event time, not its arrival time, so recovered data from a store-and-forward buffer or a backfill slots into the timeline where it belongs rather than bunching at the reconnect instant. The historian also needs a defined rule for a record arriving for a time it has already stored - fill a gap, correct, or reject a duplicate - so recovery does not create duplicates or overwrite good data.

More in Historians, IIoT & Industrial Data
Cloud vs edge historian placement  •  Backfilling a historian from CSV  •  Configure Historian Collector Compression  •  Historian export over ODBC  •  HMI vs Historian Mismatch  •  All Historians, IIoT & Industrial Data →
Free SCADA operator training
Merobix University - 70 video lessons & 261 quiz questions, from first login to compliance reporting. No demo call required.
Start free →