^SO - Set Offset (for Real-Time Clock)
Defines the secondary or tertiary clock as a fixed offset from the primary one, for printing a second time zone or an expiry date.
A printer has one clock but three readings of it. ^SO defines the second and
third as offsets from the primary, which lets a label print a best-before date
without a calculation by the sender. Set the offset to the shelf life, and the
printer does the date arithmetic. The printer reads each offset against the
primary clock on every run, so one format stays correct on every later run.
Syntax
^SOa,b,c,d,e,f,gSupport
Every documented parameter renders the same output Labelary produces.
Labelary renders this command.
Parameters
aClock to setrequired · one of a setWhich of the two offset clocks this command defines. Use ^ST for the primary clock.
- Invalid value
- enough to make the whole command be ignored. A number other than 2 or 3 discards the command, so that clock stays undefined (measured 2026-08-16).
- Test coverage
- No documented value is exercised by a test (2, 3). The invalid-value rule is pinned by 2 tests.
2- Secondary clock
3- Tertiary clock
bMonths offsetoptional · integerHow many months to add to the primary clock for this secondary or tertiary clock. Negative values move the clock backwards.
- Default
- 0
- Accepted range
- -32000 to 32000
- Invalid value
- clamped to the nearest allowed value. Clamped to the bound. A non-numeric value counts as zero (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 1 test.
cDays offsetoptional · integerHow many days to add to the primary clock for this secondary or tertiary clock. Negative values move the clock backwards.
- Default
- 0
- Accepted range
- -32000 to 32000
- Invalid value
- clamped to the nearest allowed value. Clamped to the bound. A non-numeric value counts as zero (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.
dYears offsetoptional · integerHow many years to add to the primary clock for this secondary or tertiary clock. Negative values move the clock backwards.
- Default
- 0
- Accepted range
- -32000 to 32000
- Invalid value
- clamped to the nearest allowed value. Clamped to the bound. A non-numeric value counts as zero (measured 2026-08-16).
- Test coverage
- No test at the minimum, maximum or one step outside the range. The invalid-value rule is not pinned by a test.
eHours offsetoptional · integerHow many hours to add to the primary clock for this secondary or tertiary clock. Negative values move the clock backwards.
- Default
- 0
- Accepted range
- -32000 to 32000
- Invalid value
- clamped to the nearest allowed value. Clamped to the bound. A non-numeric value counts as zero (measured 2026-08-16).
- Test coverage
- No test at the minimum, maximum or one step outside the range. The invalid-value rule is not pinned by a test.
fMinutes offsetoptional · integerHow many minutes to add to the primary clock for this secondary or tertiary clock. Negative values move the clock backwards.
- Default
- 0
- Accepted range
- -32000 to 32000
- Invalid value
- clamped to the nearest allowed value. Clamped to the bound. A non-numeric value counts as zero (measured 2026-08-16).
- Test coverage
- No test at the minimum, maximum or one step outside the range. The invalid-value rule is not pinned by a test.
gSeconds offsetoptional · integerHow many seconds to add to the primary clock for this secondary or tertiary clock. Negative values move the clock backwards.
- Default
- 0
- Accepted range
- -32000 to 32000
- Invalid value
- clamped to the nearest allowed value. Clamped to the bound. A non-numeric value counts as zero (measured 2026-08-16).
- Test coverage
- No test at the minimum, maximum or one step outside the range. The invalid-value rule is not pinned by a test.
Behavior
^SO prints nothing by itself. It prepares a clock for ^FC to read. ^FC's
second and third arguments name the indicator characters for the secondary and
tertiary clocks, so the indicator ties a field to a clock. A field with the
secondary indicator and no ^SO2 in the format reads an undefined clock.
The guide accepts only one ^SO2 per label. A label that needs two
different offsets must use ^SO3 for the second, which is why the tertiary
clock exists.
The printer adds all six offsets together, so ^SO2,1,15 is one month and
fifteen days ahead. A negative value runs the clock backwards, which is how a
"manufactured on" date follows from a print date.
Order matters. Put the ^SO, and the ^ST it offsets from, ahead of the fields
that read them, because the parser reads a format in sequence.
Tested behavior
Differences from the specification
Labelary against the ZPL II guide
Where Labelary — our compatibility target — behaves differently from the printed specification.
- An offset clock no
^SOdefines reads the printer's own clock, not the primary clock, so^STleaves it where it is (measured 2026-08-16). — not pinned by a test - The offset resolves at the command. An
^STafter an^SOmoves the primary clock alone (measured 2026-08-16). — not pinned by a test - A month or year offset clamps the day into its target month, months first: 31 January 2023 with
^SO2,1,,1is 28 February 2024 (measured 2026-08-16). — not pinned by a test
Example
A packing date and a best-before date one week later, both derived from a single clock reading:
^XA
^ST11,12,2023,22,50,00,M
^SO2,,7
^FO40,40^A0N,40,40^FC%,{^FDPacked: %m/%d/%Y^FS
^FO40,110^A0N,40,40^FC%,{^FDBest before: {m/{d/{Y^FS
^XZ
Related commands
^STSet Date and Time (for Real-Time Clock)Sets the printer's primary clock to an explicit date and time.^SLSet Mode and Language (for Real-Time Clock)Chooses which moment the clock reports, and the language of its month and day names.^FCField ClockMarks characters in the field data as real-time-clock placeholders.^KDSelect Date and Time Format (for Real-Time Clock)Chooses the date and time layout on the printer's front panel and configuration labels.