The vibration monitoring data for a concentrator’s SAG mill was consistently 10 hours ahead of reality. Not 10 hours late — 10 hours into the future. Alarms that should have correlated with the morning shift startup were timestamped at 7pm. Maintenance events that happened at 2pm appeared at midnight.

The process control team swore the SCADA was correct. The historian team swore the historian was correct. Both were right, from their perspective. The problem was in between — the OPC server translating timestamps between the PLC and the historian was applying a UTC offset in the wrong direction.

How OPC timestamps work (and diverge)

OPC DA (Data Access), the older standard that still runs the majority of industrial sites, doesn’t enforce a timestamp convention. The specification says timestamps should be UTC, but PLCs — the devices that generate the data — often store time in local time because that’s what the operator interface displays. The PLC doesn’t know or care about UTC. It knows that the shift starts at 6:00 and the reading happened at 6:00.

The OPC server sits between the PLC and the historian. It reads a value and a timestamp from the PLC and presents them to the historian client. If the PLC timestamp is local time and the OPC server assumes it’s UTC, the server applies the local-to-UTC offset in the wrong direction. In UTC+10 (Australian Eastern Standard Time), a 6:00am local reading becomes either 8:00pm the previous day (if the offset is subtracted) or 4:00pm (if it’s added). Both are wrong. One is 10 hours off, the other is 14 hours off.

OPC UA, the newer standard, mandates UTC for all timestamps. But many mining sites run OPC DA because the PLCs and DCS systems predate UA, and replacing them means downtime that no production manager will authorise.

Daylight saving makes it worse

Australian mining operations span multiple timezone behaviours. Western Australia doesn’t observe daylight saving. Queensland doesn’t. New South Wales, Victoria, and South Australia do. A mining company with operations across states has sites on different offsets for half the year.

When daylight saving transitions happen, the OPC timestamp problem doesn’t just shift your data — it creates duplicates or gaps. During the autumn transition (clocks go back one hour), the same local hour occurs twice. A PLC recording in local time produces two readings at “2:30am” — one before the transition and one after. The OPC server, assuming UTC, maps them both to the same UTC timestamp. The historian stores the second value and overwrites the first. You’ve lost an hour of data.

During the spring transition (clocks go forward), the hour from 2:00am to 3:00am doesn’t exist in local time. The PLC skips from 1:59am to 3:00am. The historian sees a one-hour gap in the data. Your analytics pipeline, expecting continuous readings, flags it as a sensor outage or equipment downtime.

Finding the problem in your data

The timestamp shift is obvious once you know to look for it, but subtle enough to go unnoticed in dashboards and reports. A 10-hour shift doesn’t make the data look broken — it just makes it look like things happened at different times.

Three diagnostic checks:

Cross-reference with a known event. Find a maintenance event with a precise timestamp — a mill shutdown, a conveyor trip, an alarm that was logged in the CMMS. Query the historian for the same event. If the timestamps don’t match, the offset tells you exactly what went wrong.

Look for DST artifacts. Query for duplicate timestamps in autumn (April in Australia) and gaps in spring (October). If you find them, you have a local-time-to-UTC conversion problem.

Check the OPC server’s timezone configuration. Most OPC servers have a setting for how they handle timestamps from the data source. Matrikon, Kepware, and the built-in AVEVA OPC servers all handle this slightly differently. The setting might be called “Source timestamp adjustment,” “Device timestamp mode,” or buried in an advanced configuration tab that nobody opened since commissioning.

Fixing it at the source vs. fixing it in the pipeline

The correct fix is at the OPC server level: configure it to treat PLC timestamps as local time and convert correctly to UTC before passing them to the historian. This requires the OPC server to know which timezone the PLC is in, which is straightforward for a single site but complex for a multi-site SCADA architecture where one OPC server aggregates from PLCs across timezones.

If you can’t fix the source — and in mining operations, changing OPC server configuration requires a change management process that can take weeks — you fix it in the data pipeline. Apply the inverse offset during extraction, handling DST transitions by mapping each reading’s raw timestamp to the correct UTC value based on the site’s timezone rules.

I use Python’s zoneinfo module (or pytz on older systems) to localise the raw timestamps to the site’s timezone and then convert to UTC. The critical detail is that you must localise first, then convert — not the other way around. If you subtract the offset directly, you’ll get the DST transitions wrong.

from zoneinfo import ZoneInfo

site_tz = ZoneInfo("Australia/Sydney")
raw_dt = raw_dt.replace(tzinfo=site_tz)
utc_dt = raw_dt.astimezone(ZoneInfo("UTC"))

Why this matters beyond the historian

If your data platform ingests historian data — and most mining analytics platforms do — the timestamp problem propagates to every downstream calculation. Shift reports attribute production to the wrong shift. Correlations between process variables and maintenance events are offset. Machine learning models trained on misaligned data learn the wrong patterns.

The timestamp was wrong before your pipeline touched it. But your pipeline is where it becomes your problem.