S7-1200 Time of Day DST Overwrite: Diagnosing 1215C Clock Drift

David Krause12 min read
S7-1200SiemensTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Problem Description

An Siemens S7-1200 CPU 1215C (firmware V4.x) was commissioned with the following time configuration in TIA Portal:

  • Time zone: UTC+01:00 Europe/Zagreb
  • Daylight Saving start rule: Last Sunday of March, 02:00 CET
  • Daylight Saving end rule: Last Sunday of October, 03:00 CEST

Two months after commissioning — immediately after the October DST end transition — the reported local time on the PLC started to lag the actual local time by exactly one hour (60 minutes). The reported UTC time remained correct, indicating the offset was applied in the wrong direction or that DST rules were being applied twice. Report timestamps, audit trails, and shift logs generated from PLC tags carried an incorrect timestamp for the entire post-DST period.

The engineer removed the DST block from the hardware configuration to allow manual overwriting from the HMI, but the same one-hour lag persisted. After enabling NTP synchronization against a SCADA workstation, the PLC time appeared to "flip-flop" — every NTP poll (minimum configurable interval is 10 seconds) caused the displayed time to briefly drop back one hour, then snap forward again as the local-time conversion was re-applied. The engineering team confirmed that no user logic was writing to the system clock via WR_SYS_T (Set time of day) or SET_TIMEZONE.

Critical: S7-1200 CPUs maintain two independent clocks: System time (UTC, internally always UTC) and Local time (UTC + configured TZ + DST offset). Reading the wrong clock source is the most common cause of "the time is wrong by exactly one hour" symptoms.

S7-1200 Time Architecture: System Time vs. Local Time

Every S7-1200 CPU tracks time as UTC internally (system time). The CPU then exposes a derived local time by applying the configured time-zone offset and the DST rule defined in the device configuration. Whether a particular instruction, tag, or HMI field returns the system or local value depends on the tag path or the instruction variant used.

Source Returns Typical Use
PLC tag %SystemTime (system clock tag) Local time (DST-adjusted) HMI display, time-stamped reports
PLC tag %LocalTime (legacy) Local time Operator displays
RD_SYS_T (Read system time / clock) System time (UTC) – DTL format UTC logging, NTP client comparisons
RD_LOC_T (Read local time) Local time – DTL format Local-time logging, scheduling
WR_SYS_T (Set time of day) Writes UTC; DST/TZ derived after write NTP, manual time set from HMI
T_CONFIG / T_CTRL / T_CONV Per-instruction behavior (see manual) Time conversion, timer blocks

If the application reads RD_SYS_T and then expects a local-time result, or if the HMI is bound to a tag that returns UTC without conversion, the time will be off by the configured offset (typically 1 h or 2 h depending on DST state). See the official S7-1200 Date, time-of-day, and clock functions reference for ENO behavior and tag references.

Root Cause Analysis

After working through the diagnostic checklist below, the failure mode observed here matches DST-rule re-application after a TIA Portal download: the project-side hardware configuration had the DST rules defined, but the running CPU retained its pre-download local-time offset of +02:00 for the CEST portion of the year. When the calendar rolled past the October end rule, the project would have reduced the offset to +01:00, but because the running CPU had not fully re-applied the rule set, it continued to display UTC+02:00 as if still in summer time — producing a one-hour-forward display. Because the SCADA / NTP source was writing UTC, the user's perception of "one hour behind" depended on which clock face the application bound.

The secondary fault observed — flip-flopping under NTP polling — is caused by the interaction between WR_SYS_T and the local-time derivation: every NTP write resets UTC, then the local time is re-calculated. If the DST block is inconsistent (for example, DST rule still active for an end-date that has passed, or DST rule missing entirely), each re-derivation can yield a different offset until the rule set is rebuilt.

Common root causes for "one hour off" reports on S7-1200

  1. Reading UTC where local time is expected. Many engineers assume the system clock tag is local. It is UTC.
  2. DST rule not downloaded / not committed. A change to the time-zone or DST rule requires a full configuration download and, in some firmware versions, a STOP/RUN transition to take effect.
  3. Time-zone configured but DST rule absent. Without a DST rule, the local time equals UTC + TZ offset year-round. With a DST rule but no end-date, the offset can stick at +02:00.
  4. Multiple writers to the clock. HMI time set, NTP, and a logic-driven WR_SYS_T all racing against each other.
  5. CPU battery low / removed. Without battery backup, the real-time clock loses time on power-cycle and reverts to a default that may not match project TZ/DST.
  6. Project online vs. offline mismatch. After editing the device configuration (Properties > Time of day), the change must be downloaded; "Go online" alone does not push new TZ/DST data.

Diagnostic Procedure

Follow this sequence before changing any project configuration. Capture each value into a data block for post-mortem review.

  1. Verify project vs. running configuration
    In TIA Portal, right-click the CPU → Online & DiagnosticsTime of day. Compare the displayed Time zone and Daylight saving values against the offline project (Device configuration → Properties → Time of day). If they differ, the running CPU is using stale TZ/DST data. The Time section on the lower-left also shows PG/PC time side-by-side with CPU time for direct comparison.
  2. Capture both clocks into a DB
    Add a global DB with two DTL tags and the following logic in OB1 (or a cyclic OB):
    // OB1 – cyclic capture of system and local clocks
    "diagDB".systemTime := RD_SYS_T();   // UTC
    "diagDB".localTime  := RD_LOC_T();   // Local (TZ + DST applied)
    "diagDB".deltaSec   := TIME_TO_INT("diagDB".systemTime - "diagDB".localTime);
    The expected delta for UTC+01:00 in winter (CET) is -3600 s and -7200 s in summer (CEST). Any value outside ±10 s of these baselines confirms a TZ/DST problem.
  3. Inspect the diagnostic buffer
    Online & Diagnostics → Diagnostic buffer. Look for entries tagged Time changed by ..., Time set by NTP, or Time jump. These entries record each WR_SYS_T invocation.
  4. Search the program for clock writers
    Cross-reference the project for any call to WR_SYS_T, SET_TIMEZONE, the Time set HMI function, and the Set time of day system function block. Disable all writers except the one chosen as the master (typically NTP).
  5. Check the battery / power-fail behavior
    Online & Diagnostics → Diagnostics status. A "Battery exhausted" or "Battery low" status indicates the buffered real-time clock cannot retain time across power cycles and will revert to the default 01.01.2000 00:00 in UTC.
  6. Validate HMI bindings
    On the HMI side, confirm the time field reads from a tag whose path is %SystemTime (local time) — not RD_SYS_T. If the HMI is bound to the wrong tag it will display UTC regardless of the PLC's local time.

Solution

Apply the following changes in the order listed. After each step, download to the CPU and verify with the diagnostic procedure above.

  1. Re-establish the TZ/DST configuration
    Open Device configuration → Properties → Time of day and set:
    • Time zone: (UTC+01:00) Sarajevo, Skopje, Warsaw, Zagreb
    • Activate Daylight saving time: Yes
    • DST start rule: Last Sunday of March, 02:00, +01:00 (switch standard → daylight, offset +01:00)
    • DST end rule: Last Sunday of October, 03:00, 00:00 (switch daylight → standard, offset 0)
    Compile (Hardware & Software, "Rebuild all") and download to the CPU. After download, perform a STOP → RUN transition to commit the new TZ/DST table on older firmware (V4.0–V4.2); V4.4+ accepts the new rule set at RUN.
  2. Pick a single clock master
    Disable the HMI Set time of day function. Disable any user program call to WR_SYS_T. Leave only the NTP client as the writer. The NTP server in the SCADA workstation should be configured to serve UTC, not local time.
  3. Tune the NTP poll interval
    S7-1200 supports a minimum NTP poll of 10 s on firmware V4.2+ (server interval Synchronization interval in device configuration → Time of day → NTP). 10 s is acceptable when the only writer is NTP; the flip-flop will not occur because WR_SYS_T and the local-time derivation are now consistent. For a stable display, increase the interval to 60 s or 300 s to reduce diagnostic-buffer churn.
  4. Replace the CPU battery if low
    For the 1215C, the buffer battery is a CR1025 lithium cell accessible behind the lower access flap. Power down the CPU, replace the cell, power up, then re-trigger NTP sync.
  5. Re-bind HMI time field
    In the HMI project, change the binding of the clock display from any custom tag to %SystemTime (local). For KTP and Comfort Panels this is found under Connections → Area pointers → Date/Time.
  6. Audit historical data
    For the affected post-DST period, re-stamp any reports using UTC + manual offset knowledge. Add a one-line note to the audit log indicating the time offset and the affected window.

Working with RD_SYS_T and RD_LOC_T

The two instructions return a DTL (date-and-time, 8-byte) structure. A practical ladder/ST snippet for computing the local-vs-system delta in seconds:

// Compute local - system delta in seconds
#localT  := RD_LOC_T();    // DTL with local offset applied
#systemT := RD_SYS_T();    // DTL, always UTC
#delta   := DTL_TO_INT(#localT) - DTL_TO_INT(#systemT); // seconds

IF ABS(#delta - (-3600)) > 10 AND ABS(#delta - (-7200)) > 10 THEN
    "diagDB".timeInvalid := TRUE;   // latch a fault bit
END_IF;

For more advanced conversions (for example, producing a Unix timestamp for an NTP client running inside the PLC), the S7-1200 Date and time-of-day instructions page documents T_CONV, T_ADD, and T_SUB which operate on the TIME and DTL types.

Verification

After each configuration change, run this verification matrix:

Check Expected (winter / CET) Expected (summer / CEST) How to read
RD_LOC_T - RD_SYS_T -3600 s ± 1 s -7200 s ± 1 s DB tag in TIA Portal watch table
Online & Diagnostics → Time of day → PLC time vs. PG/PC time Match ±2 s Match ±2 s Lower-left of working pane
HMI displayed time vs. wall-clock local Match ±1 s Match ±1 s HMI faceplate
Diagnostic buffer entries <em>Time changed</em> One per NTP poll, no jumps One per NTP poll, no jumps Diagnostic buffer
Report timestamp for a known event Local time, no offset Local time, no offset Sample report

NTP Configuration Details

NTP on the S7-1200 is configured under Device configuration → Properties → Time of day → NTP. Key parameters:

Parameter Setting Notes
NTP server address SCADA PC IP, or pool.ntp.org Up to 4 servers; first reachable wins
Update interval 10 s (min), 60 s recommended Shorter intervals increase CPU load and diagnostic-buffer churn
Time zone of NTP source UTC NTP always carries UTC; do not point the PLC at a local-time source
Authentication Optional (MD5 / SHA-1) Use when network is shared with non-trusted devices
Firmware requirement V4.2 minimum for full NTP client Earlier firmware lacks NTP; use SIMATIC Time Sender or external master clock
Note: NTP polls below 10 s are not configurable on any S7-1200 firmware. If 10 s granularity is unacceptable, replace the NTP client with a master clock broadcast over PROFINET, or accept the manual set from a trusted master once per shift.

Edge Cases and Field-Proven Caveats

  • Firmware V4.0 / V4.1 DST behaviour. On early V4.x firmware, changing the DST rule set requires a STOP/RUN transition; a download at RUN does not re-apply the DST table until the next OB1 scan after a power-cycle.
  • CPU 1212C vs 1215C. Both share the same time-of-day firmware path; the 1215C's higher part number does not change DST handling.
  • Battery removal during commissioning. If the battery is removed or never installed, the PLC's real-time clock starts from the default (2000-01-01 00:00 UTC). The CPU will not flag this on first start; NTP must be the trusted source until the battery is verified.
  • Multi-project / multi-master. When the same SCADA serves many PLCs, ensure the SCADA NTP server is itself synchronized to a stratum-1 source. A drifting SCADA clock will propagate drift to every PLC that polls it.
  • Summer/winter transition windows. At the exact DST transition (last Sunday of March 02:00 → 03:00 and last Sunday of October 03:00 → 02:00), do not schedule logic that depends on a one-hour monotonic counter. Schedule such logic for 30 minutes after the transition.

Troubleshooting Matrix

Symptom Likely Cause Action
Time is exactly 1 h ahead of UTC Local-time tag bound to a UTC source plus an extra TZ offset Re-bind HMI to %SystemTime tag
Time is exactly 1 h behind after October DST rule not applied; offset stuck at +02:00 Re-download hardware config and STOP/RUN
Time flip-flops every 10 s Multiple writers (NTP + HMI + logic) racing Disable all but one writer
Time is 2 h behind after October TZ set to UTC+02:00 with DST adding +01:00 incorrectly Set TZ to UTC+01:00 and enable DST
Time drifts slowly after power-cycle Battery exhausted Replace CR1025 battery on 1215C
Time is correct on PG but wrong on HMI HMI bound to UTC tag or wrong area pointer Use Date/Time area pointer
Time reads 01.01.2000 after power-cycle Battery removed, NTP not running Install battery, enable NTP, force sync

Safety and Audit Considerations

Time-of-day errors on a logged-data system have audit consequences even if no process upset occurs. Treat any one-hour or two-hour offset in report timestamps as a data-integrity event and document the affected window. If the PLC is part of a safety-related function (F-CPU 1215FC, F-CPU 1214FC), do not rely on the PLC clock for safety event time-stamping — use the F-CPU's diagnostic buffer entries which carry their own sequence counters and are independent of the user TZ/DST configuration.

FAQ

Why does my S7-1200 1215C show the wrong time after the October DST end date?

The CPU maintains UTC internally and derives local time using the TZ/DST rule set. After the October transition, the offset must drop from +02:00 to +01:00. If the rule set was not re-downloaded, or if the running CPU retained the +02:00 offset, the local-time display will lag real local time by one hour. Re-download the hardware configuration and perform STOP/RUN to commit the new DST table.

What is the difference between RD_SYS_T and RD_LOC_T on the S7-1200?

RD_SYS_T returns the system time in UTC as a DTL value. RD_LOC_T returns the local time after applying the configured time-zone and DST offset. Use RD_LOC_T for operator displays and RD_SYS_T for UTC logging or NTP comparisons. See the official S7-1200 Date, time-of-day, and clock functions reference for full behavior.

What is the minimum NTP poll interval on an S7-1200?

10 seconds on firmware V4.2 and later. Shorter intervals are not configurable. For most plant networks, 60 s or 300 s is sufficient and reduces diagnostic-buffer churn.

Do I need a STOP/RUN transition after changing the DST settings?

On firmware V4.0 to V4.2, yes — the DST rule table is committed at the next STOP/RUN. On V4.4 and later, the new rule set is accepted at RUN. Always verify with the Online & Diagnostics "Time of day" pane after download.

How do I stop the PLC time from "flip-flopping" every 10 seconds under NTP?

Ensure only one writer (the NTP client) calls WR_SYS_T. Disable the HMI "Set time of day" function and any user logic that writes the clock. With a single writer, each NTP poll writes a consistent UTC value and the local-time derivation produces a stable result until the next poll.

Back to blog