Convert S7 DATE_AND_TIME to String in WinCC flexible 2008
The Siemens SIMATIC S7 DATE_AND_TIME (DT) data type is an 8-byte BCD-encoded value used to represent calendar date and time of day inside the CPU. WinCC flexible 2008 supports the Date and Time tag type natively, but many panel projects still rely on string-formatted output for operator displays, logs, and event stamping. This article documents the field-proven method to read each DT field from the PLC, convert the BCD nibbles to integer, and render a formatted string on an HMI panel without requiring additional hardware.
DTL instead).Overview of the DATE_AND_TIME Data Type
The DATE_AND_TIME data type (IEC 61131-3) occupies 8 bytes in BCD format. Each byte stores one calendar element, except the last two bytes which combine sub-second resolution and weekday. The complete byte map (Siemens entry ID 25629271) is shown below.
| Byte | Content | S7 structure element | WinCC format hint |
|---|---|---|---|
| 0 | Year (BCD, 0–99, offset 1990 → 1990–2089) | YEAR |
yyyy |
| 1 | Month (BCD, 1–12) | MONTH |
m |
| 2 | Day (BCD, 1–31) | DAY |
d |
| 3 | Hour (BCD, 0–23) | HOUR |
h |
| 4 | Minute (BCD, 0–59) | MINUTE |
n |
| 5 | Second (BCD, 0–59) | SECOND |
s |
| 6 | 1/10 second (high nibble) + 1/100 second (low nibble) | MILLISEC1 |
— |
| 7 | 1/1000 second (high nibble) + weekday 1=Sunday … 7=Saturday (low nibble) | MILLISEC2 |
— |
Reference: Siemens TIA Portal Help — DATE_AND_TIME (date and time of day). The format and structure are identical between STEP 7 V5.x and TIA Portal because the data type is anchored in the IEC 61131-3 standard.
BCD Encoding and Decoding Rules
Each calendar nibble is encoded as a Binary-Coded Decimal (BCD) value. The low nibble holds the ones digit (0–9), the high nibble holds the tens digit (0–9). The 8-byte DT therefore stores 16 BCD digits plus a 4-bit weekday.
Decoding a single BCD byte to integer (LAD/STL convention):
// BCD -> INT (works for YEAR, MONTH, DAY, HOUR, MINUTE, SECOND)
L %B "DT_DB".YEAR // load BCD byte
BTI // BCD to Integer (STEP 7 instruction)
T %MW 100 // store decoded year
Manual decoding formula if BTI is not available (e.g. in a script):
int_value = (bcd_byte >> 4) * 10 + (bcd_byte & 0x0F)
Examples:
| BCD byte (hex) | Decoded value | Meaning |
|---|---|---|
| 0x23 | 23 | Day 23 / Hour 23 / Year 2023 (high nibble = 2 → +20) |
| 0x05 | 5 | Month 5 / Second 5 |
| 0x90 | 90 | Year 1990 (add 1900 base) |
year_full = 1900 + decoded_year when the decoded value is < 90, otherwise year_full = 2000 + decoded_year. This is the same rule used by WinCC flexible's Date and Time tag type. Verify against your project's clock master if ambiguous.Prerequisites
- WinCC flexible 2008 SP2 or later installed (ES + RT).
- STEP 7 V5.4/V5.5 project with an S7-300/400 CPU whose system clock returns a DT (e.g.
DT1fromSFC 1 READ_CLK). - A DB that exposes the DT as a multi-instance, e.g.
DB100starting at byte 0 with a tag declaredPLC_DT : DATE_AND_TIME. - MPI/Profibus or TCP/IP (S7-1200/1500) connection configured between the panel and the PLC.
- Optional: PLCSIM (V5.4 SP5 or later) to test offline before connecting to factory hardware — recommended when no physical CPU is on the bench.
Step-by-Step: Method A — Native Date/Time Tag in WinCC flexible
This is the simplest path and should be tried first.
Step A1 — Declare the DT in the S7 DB
Open STEP 7, navigate to the source DB, and add a tag of data type DATE_AND_TIME:
DATA_BLOCK DB100
STRUCT
PLC_DT : DATE_AND_TIME; // 8 bytes, occupies DBW 0..7
bStatus : BOOL; // optional status flag
END_STRUCT;
END_DATA_BLOCK
Step A2 — Populate the DT with the CPU clock
Call SFC 1 (READ_CLK) in OB1 (or any cyclic OB) to refresh the tag continuously:
CALL "READ_CLK"
RET_VAL := MW 200
CDT := "DB100".PLC_DT
Step A3 — Configure the WinCC flexible tag
- In the WinCC flexible project tree, expand Communication → Tags.
- Create a new tag
PLC_DateTimewith:- Connection: the S7 connection pointing to the CPU hosting DB100.
-
Address:
DB 100 DBD 0(S7-300/400) orDB 100 DBB 0with length 8 (panel-side length field auto-resolves). - Data type: Date and Time (matches the 8-byte BCD DT).
- Drop the tag on an IO field or Date/Time field on the screen. The panel driver will automatically decode BCD, apply the 1900/2000 base rule, and render the local time zone.
Step A4 — Verify
Start PLCSIM, trigger a value change in the DT (e.g. via VAT table), and confirm the panel field updates within one acquisition cycle. If the field shows --.--.----, the connection or address is wrong; jump to the troubleshooting matrix at the end of this article.
Step-by-Step: Method B — String Output for Logs and Free-Form Displays
When the HMI must show a string such as 2024-03-12 14:23:05 (for an alarm history or a screen caption), declare the tag in WinCC flexible as String length 19 and build it on the PLC side using the conversion blocks described in Siemens entry 25629271.
Step B1 — Convert each BCD byte with I_STRING
The I_STRING function from the STEP 7 IEC function blocks library (Standard Library → IEC Function Blocks) converts a 16-bit integer to a string. Feed it the decoded year, month, day, hour, minute, and second:
// Example: build a 19-char timestamp into DB200.STRING_TS
// Assumes DB100.PLC_DT is the source DATE_AND_TIME
// 1) Decode BCD bytes to INT using BTI
L "DB100".PLC_DT.YEAR // BCD
BTI
T #iYear
L "DB100".PLC_DT.MONTH
BTI
T #iMonth
L "DB100".PLC_DT.DAY
BTI
T #iDay
L "DB100".PLC_DT.HOUR
BTI
T #iHour
L "DB100".PLC_DT.MINUTE
BTI
T #iMinute
L "DB100".PLC_DT.SECOND
BTI
T #iSecond
// 2) Convert each INT to a 4-char or 2-char string with I_STRING
CALL I_STRING
I := #iYear
RET_VAL := P#DB200.DBX 0.0 STRING[4]
CALL I_STRING
I := #iMonth
RET_VAL := P#DB200.DBX 4.0 STRING[2]
Concatenate the resulting substrings with literal hyphens, colons, and a space using CONCAT (STRING) / DI_STRNG (DINT to string) plus the standard FC chain from the Siemens FAQ entry. The compiled sample block set referenced in entry 25629271 wraps the six I_STRING calls plus concatenation logic into a single reusable FC (commonly called FC_DT_to_String).
Step B2 — Declare the destination string
DATA_BLOCK DB200
STRUCT
STRING_TS : STRING[19]; // 20 bytes (1 length header + 19 chars)
END_STRUCT;
END_DATA_BLOCK
Step B3 — Configure the WinCC flexible tag
- Create a tag
Timestampof data type String, length 19. - Map it to
DB 200 DBB 1(skip the 1-byte maximum-length header that S7 strings prepend). - Place a Symbolic IO field with output mode and set display format String.
- Disable input so operators cannot overwrite the timestamp.
Step-by-Step: Method C — Script-Based Conversion on the Panel
If modifying the PLC program is not permitted, run the BCD-to-string conversion entirely on the HMI using a WinCC flexible VBScript. This is the typical path for retrofit projects where the DT is already exposed but no FC has been added.
Step C1 — Expose the eight raw bytes
Declare the tag as Byte Array with length 8, or as eight individual byte tags. Example for a byte array at DB 100 DBB 0:
- Tag name:
DT_Bytes - Type: Byte Array, length 8
Step C2 — Conversion script (VBScript, runs on value change)
' WinCC flexible VBScript — convert 8 BCD bytes to a formatted string
Dim b(7), i
For i = 0 To 7
b(i) = SmartTags("DT_Bytes_" & i)
Next
' BCD decode helper
Function BCD2Int(byval x)
BCD2Int = (x \ 16) * 10 + (x And &HF)
End Function
Dim y, mo, d, h, mi, s
y = 2000 + BCD2Int(b(0)) ' adjust 1900/2000 base per project
mo = BCD2Int(b(1))
d = BCD2Int(b(2))
h = BCD2Int(b(3))
mi = BCD2Int(b(4))
s = BCD2Int(b(5))
' Zero-pad to two digits
Function Pad2(byval n)
If n < 10 Then
Pad2 = "0" & CStr(n)
Else
Pad2 = CStr(n)
End If
End Function
SmartTags("Timestamp") = CStr(y) & "-" & Pad2(mo) & "-" & Pad2(d) & _
" " & Pad2(h) & ":" & Pad2(mi) & ":" & Pad2(s)
Wire the script to the Value change event of the byte-array tag, or to a 1-second scheduled trigger so the display refreshes without requiring the PLC to republish the DT.
Alternative: TIA Portal and S7-1200/1500 Considerations
Modern S7-1200/1500 controllers no longer favor the BCD-encoded DATE_AND_TIME. TIA Portal uses the DTL structure (12 bytes) with fields YEAR, MONTH, DAY, WEEKDAY, HOUR, MINUTE, SECOND, NANOSECOND. The byte-level decoding rules above do not apply to DTL — the fields are plain INT or DINT values. If the panel is connected to an S7-1500, use the DTL tag type in WinCC (TIA) and the DTL_to_STRING standard block; for legacy WinCC flexible 2008 panels bridging to S7-1500, map the DTL fields to individual INT tags and build the string either in the PLC or on the panel.
Verifying the Result
After commissioning, run the following verification checks:
-
Static test: Force a DT value in PLCSIM (e.g.
DT#2024-12-31-23:59:59) and confirm the panel renders the matching string without dropped digits. -
Boundary test: Force
DT#2089-12-31-23:59:59andDT#1990-01-01-00:00:00. These are the lower and upper edges of the 1990–2089 window; they verify the year-base rule. -
Live test: Compare the panel value against the value returned by
SFC 1in the PLC (cross-check via VAT or online watch table). Drift greater than the panel's acquisition cycle indicates a mismatch between tag type Date and Time and a raw BCD byte view. - Time-zone test: If the project uses UTC internally, set the panel's time zone to UTC and verify the operator display is offset by the configured shift (typically local − UTC).
Troubleshooting Matrix
| Symptom | Likely root cause | Corrective action |
|---|---|---|
Panel shows ##:##:## for the time |
Tag declared as String instead of Date and Time | Re-create the tag with data type Date and Time and length 8 bytes. |
| Year is 1990 when the PLC reports 2024 | Tag length set to 6 bytes (truncated) or the year is being read as the month | Set the length to 8 bytes and verify the start address is the year field, not the month. |
String output reads 0-0-0 0:0:0 while the DT is valid |
BTI not called before I_STRING — script treats the BCD byte as binary |
Insert BTI for every field, or call the BCD2Int helper shown in Method C. |
| Month or day shows the wrong decade (e.g. month 12 displays as 18) | BCD byte interpreted as binary; e.g. 0x12 becomes 18 instead of 12 |
Apply the BCD2Int formula: (x >> 4)*10 + (x & 0x0F). |
| Connection warning "address not available" | DB number mismatch between STEP 7 and the WinCC flexible connection | Recompile the STEP 7 program, re-import the connection in WinCC flexible, or update the DB number manually. |
| PLCSIM shows the DT, but the panel value never updates | Acquisition cycle set to "On demand" and no trigger is firing | Set the cycle to Cyclic continuous at 1 s for test, then tune for production. |
| Year shows 1900+BCD instead of 2000+BCD | Project uses a custom year base; PLC year < 90 interpreted as 1900+ | Apply the rule year_full = (decoded < 90) ? 1900 + decoded : 2000 + decoded in the conversion block. |
Reference to Siemens Documentation
The byte structure and the I_STRING conversion chain described above are documented in the Siemens Industry Online Support entry ID 25629271. The modern equivalent lives in the TIA Portal help under Data types → Date and time → DATE_AND_TIME (date and time of day), which is maintained across TIA Portal V15 through V20 with identical structure.
Additional Siemens manuals that complement this article:
- TIA Portal Help — DATE_AND_TIME (date and time of day)
- STEP 7 V5.5 Standard and System Functions reference manual (entry IDs 44240604 and 12182304 in Siemens Support).
- WinCC flexible 2008 Communication user manual (entry ID 18796052 in Siemens Support) — covers the panel-side tag type Date and Time.
Field-Proven Caveats
-
Acquisition cycle. The panel driver only re-reads the DT on a trigger. If you place a DT tag on a screen with acquisition set to On demand and never call
UpdateTagfrom a script, the value will stay frozen at the first read. -
String length header. S7 strings are prefixed by a 1-byte maximum length and a 1-byte actual length. When mapping an S7 string into WinCC flexible, point the panel tag at
DBB actual_length + 1, otherwise the first displayed character is the binary length byte and the result is unreadable. - Endianness. Within a single byte the BCD encoding is endian-neutral because the high nibble is always the tens digit. Do not byte-swap the DT as a whole — that destroys the field layout.
-
Daylight saving. WinCC flexible does not automatically adjust DT tags for DST. If the operator screen must show local civil time, perform the conversion in the PLC using the local time block (e.g.
FB 3from the Standard Library) or switch to TIA Portal where DST handling is built into the panel runtime. -
S7-1200/1500 fallback. The legacy DT data type is available on S7-1200/1500 only for compatibility. For new code, use
DTLand configure the panel in TIA Portal with the matching DTL tag type.
FAQ
Which STEP 7 instruction converts a BCD date byte to an integer?
Use the BTI (BCD to Integer) instruction on each calendar byte (year, month, day, hour, minute, second). In VBScript on the panel, apply the formula (byte >> 4) * 10 + (byte & 0x0F) because BTI is not available in the panel runtime.
How is the year 2000 represented inside a DATE_AND_TIME value?
The year byte holds the two-digit year in BCD. The value 0x24 means 2024. WinCC flexible and the BTI/BCD2Int convention interpret values < 90 as 19xx and values ≥ 90 as 19xx as well (the wraparound point of the 1990–2089 window). Verify the project-specific year base against Siemens entry 25629271.
What is the difference between DATE_AND_TIME and DTL?
DATE_AND_TIME is the legacy IEC 61131-3 data type used on S7-300/400, 8 bytes in BCD. DTL is the TIA Portal data type for S7-1200/1500, 12 bytes in plain binary, with explicit YEAR (INT), MONTH (USINT), DAY (USINT), WEEKDAY (USINT), HOUR (USINT), MINUTE (USINT), SECOND (USINT), and NANOSECOND (DINT) fields.
Can I use WinCC flexible 2008 with an S7-1500?
Yes, but only via the S7-300/400-compatible DATE_AND_TIME slot on the S7-1500, or by exposing the DTL fields as individual tags. TIA Portal with the modern WinCC runtime is the recommended path for new S7-1500 projects.
Why does my panel display 1990 as the year even though the PLC has 2024?
Most often the tag length is set to 6 bytes instead of 8, which truncates the year field and substitutes zero. Increase the length to 8 bytes and confirm the start address is the year (byte 0 of the DT). A secondary cause is reading the DT through an S7 string that strips the high nibble; in that case rebuild the string using the conversion FC chain described in Siemens entry 25629271.