zpl.tools
Real-time clock

^ST - Set Date and Time (for Real-Time Clock)

Sets the printer's primary clock to an explicit date and time.

^ST writes a date and time into the printer's real-time clock. On hardware it is a maintenance command for a printer that drifts or takes a new battery, not a per-label command. Against a rendering API it has a second and larger use. ^FC substitutes whatever the clock says, so a format with ^ST renders the same dated label every time. That is the only reproducible result from a clock field.

Syntax

^STa,b,c,d,e,f,g

Support

Supportedparsed: full · state: full · rendered: full

Every documented parameter renders the same output Labelary produces.

Labelary renders this command.

Parameters

aMonthoptional · integer

Month to set the clock to.

Default
the primary clock's own month
Accepted range
1 to 12
Invalid value
discarded, and the current value is kept. A month outside 1-12 keeps the clock's own month (measured 2026-08-16).
Test coverage
Bounds pinned: past what the shape can hold (99999999999999999999). No test at the minimum or maximum. The invalid-value rule is pinned by 2 tests.
bDayoptional · integer

Day of the month to set the clock to.

Default
the primary clock's own day
Accepted range
1 to 31
Invalid value
discarded, and the current value is kept. A day outside 1-31 keeps the clock's own day. A day the month does not have rolls forward instead (measured 2026-08-16).
Test coverage
No test at the minimum, maximum or one step outside the range. The invalid-value rule is pinned by 1 test.
cYearoptional · integer

Four-digit year to set the clock to.

Default
the primary clock's own year
Accepted range
1998 to 2097
Invalid value
discarded, and the current value is kept. A year outside 1998-2097 keeps the clock's own year, so a two-digit year is rejected (measured 2026-08-16).
Test coverage
No test at the minimum, maximum or one step outside the range. The invalid-value rule is pinned by 1 test.
dHouroptional · integer

Hour to set the clock to, read against the format in g. A P adds twelve hours; an A leaves the hour as written.

Default
the primary clock's own hour
Accepted range
0 to 23
Invalid value
discarded, and the current value is kept. The bound is 23 for a 24-hour value and 11 for a 12-hour one. An hour past it keeps the clock's own hour (measured 2026-08-16).
Test coverage
No test at the minimum, maximum or one step outside the range. The invalid-value rule is pinned by 1 test.
eMinuteoptional · integer

Minute to set the clock to.

Default
the primary clock's own minute
Accepted range
0 to 59
Invalid value
discarded, and the current value is kept. A minute above 59 keeps the clock's own minute (measured 2026-08-16).
Test coverage
No test at the minimum, maximum or one step outside the range. The invalid-value rule is pinned by 1 test.
fSecondoptional · integer

Second to set the clock to.

Default
the primary clock's own second
Accepted range
0 to 59
Invalid value
discarded, and the current value is kept. A second above 59 keeps the clock's own second (measured 2026-08-16).
Test coverage
No test at the minimum, maximum or one step outside the range. The invalid-value rule is pinned by 1 test.
gHour formatoptional · one of a set

How to read the hour in d: as a 12-hour value with a meridiem, or as a 24-hour value. Any other letter reads it as 24-hour.

Default
M
Invalid value
discarded, and the default applies
Test coverage
Values exercised: P. Not exercised: A, M. The invalid-value rule is pinned by 1 test.
A
The hour is a 12-hour value before noon
P
The hour is a 12-hour value after noon
M
The hour is a 24-hour military value (default)

Behavior

^ST on its own prints nothing. It sets the clock, and ^FC reads the clock. A field takes a date only when it holds ^FC's indicator character and a format letter after it. A format with ^ST and no ^FC renders as it does without the ^ST.

Every argument is optional on its own, and defaults to the value the clock already holds. Labelary printed 14:30 on that day's date for ^ST,,,14,30 (measured 2026-07-29). The command is therefore easy to under-specify: an omitted year keeps the printer's own year, which defeats a ^ST sent for a stable render.

The printer reads the hour against g. With the default M the hour is a 24-hour value, so 22 is ten at night. With A or P it is a 12-hour value, and the letter decides the half of the day.

Set the clock before the fields that read it. The parser reads a format in order, so a ^ST after a dated field is too late for it. A ^FC field followed by ^ST11,12,2023,… printed that day's real date rather than the date in the command (measured 2026-07-29).

On a printer the whole family needs the real-time-clock option. Without it the printer ignores ^FC outright, so the placeholders print as literal text.

Tested behavior

Differences from the specification

Labelary against the ZPL II guide

Where Labelary — our compatibility target — behaves differently from the printed specification.

  • Each component the command leaves out keeps the primary clock's own value. A second ^ST therefore moves only what it names (measured 2026-08-16). — not pinned by a test
  • A day the month does not have rolls forward rather than being rejected: ^ST02,31,1999 is 3 March 1999 (measured 2026-08-16). — not pinned by a test

zpl.tools against Labelary

Where our output differs from Labelary for the same input. These are the differences that break a migration.

  • A rejected component gives the same clock in both engines, and a warning on the same argument, in a different sentence. Labelary names the value it kept; the parser cannot read the clock, so it reports the argument as ignored. — not pinned by a test

Example

A packing label pinned to a fixed moment, so the render is repeatable. The month comes first in ^ST, so 11,12 is 12 November:

^XA
^ST11,12,2023,22,50,00,M
^FO40,40^A0N,40,40^FC%^FDPacked: %m/%d/%Y %H:%M^FS
^XZ

Open in viewer