RD_SYS_T Returns UTC Time on S7-1200/S7-1500: Time Zone Fix

David Krause12 min read
SiemensTIA PortalTroubleshooting
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: RD_SYS_T Output Does Not Match TIA Portal Display

When an engineer reads the system time on a SIMATIC S7-1200 or S7-1500 CPU using the RD_SYS_T (Read time-of-day) instruction, the value at output OUT appears to be incorrect: it is several hours behind the time shown in TIA Portal under Online & Diagnostics > CPU > Time. Typical offsets reported in the field are 1 hour, 2 hours, 3 hours, or even odd half-hour offsets depending on the project location (e.g. UTC+05:30 for India, UTC+05:45 for Nepal).

The symptom is most often reported as a "RD_SYS_T ERROR" or "wrong time on the HMI", but the value is not an error code. The RD_SYS_T block returns a valid DTL (date-and-time-long) value; the engineer is simply misinterpreting what the value represents.

Field Example

  • CPU model: S7-1515-2 PN (6ES7515-2AM02-0AB0), firmware V2.9
  • CPU clock configured for: (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
  • Daylight saving: Europe start/end rules enabled
  • NTP server: pool.ntp.org, synchronization every 60 s
  • TIA Portal HMI panel (KTP1200) shows: 12:36:00 local time
  • RD_SYS_T.OUT shows: 09:36:00 (3 hours earlier)

The 3-hour difference is not a bug, not a hardware defect, and not a programming mistake. It is the documented behavior of RD_SYS_T for the S7-1200/S7-1500 system.

Root Cause: RD_SYS_T Always Returns UTC, Not Local Time

Per the official Siemens documentation, RD_SYS_T reads the current date and time-of-day of the CPU clock as a module time. On the S7-1200 and S7-1500 platforms, the module time is stored and returned in UTC (Coordinated Universal Time), also historically called GMT. The instruction does not apply the CPU's configured time zone, nor does it apply daylight saving time (DST) conversion.

Key fact: RD_SYS_T on S7-1200/S7-1500 returns UTC regardless of the time zone and DST settings in the CPU properties. This is the documented behavior in TIA Portal V15.1 through V20, and it applies to every S7-1200 firmware >= V4.0 and every S7-1500 firmware >= V1.0.

The TIA Portal Online & Diagnostics view, on the other hand, takes the raw module time and renders it in the local time zone of the engineering PC (or, more precisely, the time zone configured in the project under Languages & Resources > Time). That is why the online display and the tag value visible in the watch table appear to disagree by exactly the value of the time-zone offset plus the DST delta.

Reference Documentation

Technical Details: Instruction Interface and DTL Output

The RD_SYS_T block resides in the TIA Portal instruction palette under Extended instructions > Date and time-of-day > Time-of-day functions. Its interface is identical on every S7-1200 and S7-1500 firmware.

Parameter Declaration Data Type Description
EN Input BOOL Enable input; rising edge triggers the read
ENO Output BOOL Enable output; 1 = success, 0 = error (CPU in STOP, no valid time, etc.)
OUT Output DTL Current date and time in UTC
RET_VAL Output (S7-300/400 only) INT Error code (see below); not present on S7-1200/S7-1500

The DTL structure has the following layout (16 bytes total):

Byte Component Type Range / Meaning
0 YEAR UINT 1970 to 2554
2 MONTH USINT 1 to 12
3 DAY USINT 1 to 31
4 WEEKDAY USINT 1 (Sunday) to 7 (Saturday)
5 HOUR USINT 0 to 23 (UTC)
6 MINUTE USINT 0 to 59
7 SECOND USINT 0 to 59
8..11 NANOSECOND UDINT 0 to 999,999,999
12..15 reserved - Always 0

Because the HOUR field is already in UTC, an engineer who feeds it directly to an HMI tag (e.g. "DB_Time".systemTime.HOUR) will display UTC on the panel, not local time. The same is true for the S7-1500 web server time tag, OPC UA nodes of type DateTime, and any WinCC faceplate bound to the raw DTL.

S7-300 / S7-400 Behavior and RET_VAL Error Codes

On the older S7-300 and S7-400 platforms, RD_SYS_T uses the Date_And_Time (DT) BCD format and provides a RET_VAL word. Behavior differs from the S7-1200/S7-1500 in two important ways:

  1. The output is local time by default (the CPU's local time zone, configured in STEP 7 HW Config under CPU properties > Time of Day). This is one of the most common cross-platform confusion points during migration projects.
  2. If the output buffer is the wrong data type, or if the CPU is in STOP, an error code is returned in RET_VAL.
RET_VAL (hex) Meaning
0000 No error
8080 Date/time cannot be saved in the specified data type
80A0 The value at the OUT parameter cannot be set (e.g. invalid target area)
8xxy General error (xx = error class, y = error number; see STEP 7 system software manual)

For the official description on the S7-300/400, see RD_SYS_T: Read time-of-day (S7-300, S7-400) – TIA Portal V20 Online Help. When migrating S7-300/400 code to S7-1500, plan for the time-zone change explicitly: any program that was happy with local time on S7-300 will see a shifted value on S7-1500 after migration.

Solution 1: Use RD_LOC_T for Local Time

The S7-1500 (firmware V2.0 and later) and the S7-1200 (firmware V4.2 and later) provide the instruction RD_LOC_T (Read local time-of-day), which returns the CPU clock converted to the local time zone and DST offset defined in the device configuration. This is the correct instruction to use when the application, the HMI, or the SCADA expects the operator's wall-clock time.

RD_LOC_T Interface

Parameter Declaration Type Description
EN Input BOOL Enable input; rising edge triggers the read
ENO Output BOOL Enable output
OUT Output DTL Local date and time-of-day (UTC + configured offset + DST)

Example LAD/FBD call (single-instance DB) in TIA Portal V18+:

// Call RD_LOC_T once per second from a cyclic OB (e.g. OB1)
CALL  "RD_LOC_T" , %DB100
     EN  :=  TRUE
     ENO  =>  #ok
     OUT  =>  "HMI".localTime  // DTL, e.g. 2024-06-15-12:36:00.000

When the CPU is configured for (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna with European DST rules, RD_LOC_T.OUT in June returns the correct local time even though the CPU's internal UTC clock is one or two hours behind it.

Solution 2: Apply the Time-Zone Offset Manually in the PLC

On S7-1200 firmware < V4.2 and on S7-1500 firmware < V2.0, RD_LOC_T is not available. In those cases, derive local time from RD_SYS_T by adding the project-specific offset and DST bit. A simple SCL implementation:

// FB_LocalTime - convert RD_SYS_T (UTC) to local time
// Inputs:  iUtc         DTL   from RD_SYS_T.OUT
//          iOffsetMin   INT   offset in minutes incl. DST (e.g. 180 for UTC+3 summer)
// Output:  oLocal       DTL
// Author:  automation engineer notes
FUNCTION_BLOCK "FB_LocalTime"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT
      iUtc       : DTL;
      iOffsetMin : INT;
   END_VAR
   VAR_OUTPUT
      oLocal : DTL;
   END_VAR
   VAR
      secSinceEpoch : DINT;
      tDT           : DATE_AND_TIME;
   END_VAR
BEGIN
   // Convert DTL to seconds since 1970-01-01 00:00:00 UTC
   secSinceEpoch :=  DAT_TO_DINT( DT_DAYS(  DTL_TO_DATE(iUtc) ) ) * 86400
                    + DWORD_TO_DINT( iUtc.HOUR )      * 3600
                    + DWORD_TO_DINT( iUtc.MINUTE )    * 60
                    + DWORD_TO_DINT( iUtc.SECOND );
   // Add the offset (can be negative for west of UTC)
   secSinceEpoch := secSinceEpoch + INT_TO_DINT(iOffsetMin) * 60;
   // Convert back to DT (BCD) then to DTL
   tDT := DINT_TO_DT( secSinceEpoch );
   oLocal := DT_TO_DTL( tDT );
END_FUNCTION_BLOCK
Warning: Manual conversion is only as good as the iOffsetMin value. For DST-aware systems, swap the value at the configured DST changeover timestamps, or replace it with a tag driven by the CPU's "Time-of-day is daylight saving time" system bit (S7-1500 only, see System clock > Status).

CPU Clock Configuration in TIA Portal

The local-time behavior of RD_LOC_T and the online display depends on three parameters set in the device configuration of the CPU. Open Project tree > PLC_x > Device configuration > Properties > General > Time of day and verify the following:

  1. Time zone – select the entry that matches the plant's standard time, e.g. (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna. The setting applies to the time the CPU uses for local-time functions; it does not change the UTC value returned by RD_SYS_T.
  2. Daylight saving time (DST) – enable the regional rule that matches local legislation, e.g. Europe: last Sunday in March 02:00 to last Sunday in October 03:00. The CPU automatically advances the local time by one hour on the changeover.
  3. NTP synchronization – under Properties > General > Time of day > NTP, enable the NTP client and point it at one or more NTP servers (e.g. pool.ntp.org, or a plant-local NTP appliance). The synchronization interval defaults to 10 s on S7-1500 and is typically set to 60–600 s in production. Without NTP, drift of the CPU's RTC is on the order of a few seconds per day.

The NTP server itself always returns UTC. The CPU is responsible for converting UTC to local time when RD_LOC_T is called or when time-related system services are queried. The NTP setting on the engineering PC (and on the TIA Portal PC) is independent; it controls only how the Online & Diagnostics view renders the value.

Comparing RD_SYS_T, RD_LOC_T and WR_SYS_T

Instruction Platforms Returns DST / TZ applied? Typical Use Case
RD_SYS_T S7-1200/1500/300/400 Module time (UTC on S7-1200/1500, local on S7-300/400) No (on S7-1200/1500) Time-stamping audit logs, OPC UA DateTime tags, UTC time source for downstream gateways
RD_LOC_T S7-1500 >= V2.0, S7-1200 >= V4.2 Local time-of-day (DTL) Yes HMI time display, shift-logic, operator-facing screens, scheduled tasks
WR_SYS_T S7-1200/1500/300/400 Writes UTC to module time (S7-1200/1500) No Forcing CPU RTC, restoring time after battery replacement
SET_TIMEZONE S7-1500 only Sets TZ rule programmatically - Mobile machinery that crosses time zones

The pattern in well-designed S7-1500 programs is: RD_SYS_T drives a UTC tag, RD_LOC_T drives the HMI. Both are written to separate data blocks so OPC UA consumers and operators never accidentally read the same value for two different meanings.

Verification Steps After Applying the Fix

  1. Watch-table test. Create a watch table with the RD_SYS_T instance DB and the RD_LOC_T instance DB. Trigger RD_LOC_T with a 1-Hz pulse from a clock memory bit (e.g. Clock_1Hz). Confirm that RD_LOC_T.OUT.HOUR matches the time shown in the TIA Portal Online & Diagnostics > Time view.
  2. DST changeover test. Either wait for the next real changeover or, in the lab, force the CPU clock forward by 30 minutes with Online & Diagnostics > Set time, observe whether RD_LOC_T advances by an extra hour, then restore the time from NTP.
  3. OPC UA cross-check. Subscribe to the DTL tag via an OPC UA client (e.g. UaExpert). The client should display the local time if the CPU's time-zone setting is configured; verify the ns=…;s=…;s=…; node Server timestamp matches RD_LOC_T.OUT.
  4. HMI spot check. Bind a date/time field on a Comfort Panel or Unified Panel to the local-time DTL tag. The panel should display wall-clock time, not UTC.

Common Pitfalls and Edge Cases

  • Confusing the engineering PC's time zone with the CPU's time zone. A German engineer working remotely on a project in Saudi Arabia will see the TIA Portal Online & Diagnostics view shifted by an extra +1 h or +2 h (depending on DST) on top of the CPU's setting.
  • Migration from S7-300 to S7-1500. Existing S7-300 code reads local time with RD_SYS_T; the same code on an S7-1500 reads UTC. Add a project-wide review for time-stamped audit-trail tags before commissioning.
  • HMI log buffer. WinCC Professional and Unified log templates that take a DTL tag will silently display UTC if the binding points to a RD_SYS_T source. Always re-bind log tags to the RD_LOC_T tag.
  • Half-hour and 45-minute offsets. India (UTC+05:30), Iran (UTC+03:30 / +04:30), Nepal (UTC+05:45), and parts of Australia cannot be represented with whole-hour offsets. TIA Portal supports these via the time-zone list; verify the correct region is selected rather than approximating with a manual offset.
  • Battery-backed RTC with no NTP. A CPU that has been powered off for weeks will report a stale time. The PLC will not raise an error; RD_LOC_T.OUT will simply be wrong. Add a startup tag that flags "time not synchronized since restart" and force a re-sync.
  • Secure PLC and NTP. On S7-1500 with security enabled, NTP traffic uses NTS or signed time packets. Make sure the configured NTP server supports the same protocol; otherwise, the CPU logs a synchronization error in the diagnostic buffer (event ID 0x27 for "Time-of-day synchronization error").

Diagnostic Buffer and Online Trace

If you suspect that the time the CPU is reporting is wrong independently of the time-zone interpretation, open the diagnostic buffer (Online & Diagnostics > Diagnostics buffer) and look for the following events:

Event ID (hex) Meaning Recommended Action
0x00A1 Time-of-day has been set by user Informational; check who/when changed the time
0x00A2 Time-of-day has been set by NTP Informational; NTP sync OK
0x00A3 Time-of-day synchronization interrupted NTP server unreachable; check network and firewall
0x00A4 Time-of-day synchronization resumed Informational; NTP recovered
0x27xx Secure-communication NTP/NTS error Reconfigure NTS or relax security level

For deeper analysis, use the trace function in TIA Portal V17+ to record the DTL tag on a 100 ms cycle. Compare the recorded HOUR field with the value from an external NTP-disciplined reference clock (e.g. a smartphone in airplane mode + GPS time).

FAQ

Does RD_SYS_T return local time on an S7-1500?

No. On every S7-1200 and S7-1500 firmware version, RD_SYS_T returns the CPU module time in UTC. The TIA Portal Online & Diagnostics view renders the value in the PC's local time, which is what causes the apparent mismatch. Use RD_LOC_T (S7-1500 >= V2.0, S7-1200 >= V4.2) to obtain the local time directly.

Why does RD_SYS_T on an S7-300/400 return local time but on an S7-1500 it returns UTC?

The two platform families handle time-of-day differently. S7-300/S7-400 store and expose the CPU clock as local time in BCD format, while S7-1200/S7-1500 store the clock internally as UTC and expose it via RD_SYS_T in UTC, leaving time-zone conversion to instructions such as RD_LOC_T. This is a documented architectural change, not a bug.

What is the difference between RD_SYS_T and RD_LOC_T in STEP 7 TIA Portal?

RD_SYS_T returns the raw module time (UTC on S7-1200/S7-1500) without applying the configured time zone or daylight saving rules. RD_LOC_T applies the CPU's configured time zone and DST settings and returns the resulting local date and time as a DTL value suitable for direct display on HMIs, SCADA, or shift logs.

How do I configure NTP time synchronization on an S7-1500 CPU?

Open the CPU device configuration in TIA Portal, go to Properties > General > Time of day, enable the NTP client, enter one or more NTP server IP addresses (for example pool.ntp.org or a plant NTP appliance), and set the synchronization interval to 60–600 s. The CPU will then discipline its internal RTC against the NTP server. The NTP server always returns UTC; local time is derived only when RD_LOC_T is called.

What error codes can RD_SYS_T return on S7-300 or S7-400 CPUs?

On S7-300/S7-400, RD_SYS_T returns an error code in the RET_VAL word. Common values are 0000 (no error), 8080 (date/time cannot be saved in the specified data type), and 80A0 (OUT parameter cannot be set, for example due to an invalid target area or the CPU being in STOP). On S7-1200/S7-1500, the RET_VAL output does not exist; only ENO is available.

Back to blog