Skip to content

Value Formatting

Central formats values with .NET composite formatting. Everywhere you can shape how a value is rendered — a parameterized placeholder, a Formatting Template transform, a positional argument in a Read URL — the format you write is passed through to that engine. One syntax covers all of them, and the full Microsoft reference for standard and custom format strings applies verbatim.

This page is the shared appendix for that syntax. It is referenced from Parameterizing and from the Formatting Template transform.

The one rule that explains most surprises

A format specifier only does something when the value is already a typed value — a date, a number, a GUID. Text is passed through untouched.

{0:yyyy-MM-dd} applied to the string "2026-03-09" returns 2026-03-09 unchanged; applied to the string "03/09/2026" it also returns 03/09/2026 unchanged. It is not reformatting the date — it is ignoring the specifier, because .NET strings have no formatting behavior of their own. If the output looks exactly like the input, this is almost always why.

Use this table to know what you are holding:

SourceType you getFormat specifiers apply?
{PROP:Name}The Common Model property's real type — DateTime, decimal, bool, stringYes, for the non-string types
{CD:Name}Text (Custom Data is stored as a string)No
{PK:Name} / {FK:Name}Text (keys are stored as strings)No
{RD:Name}Whatever was stored on the Related Data itemOnly if it was stored typed
{SESSION:Name}Whatever the Get Session Values action capturedUsually text — see below
{VAR:Name}The Variable's Value Type, or the generator's outputYes, once Value Type is set
{SYS:CurrentDateTime}DateTime (UTC)Yes — defaults to O if you omit a format
{SYS:DateLastPolled} / {SYS:EventTime}DateTimeYes — always give these an explicit format
{SYS:PrimaryId} / {SYS:ParentId}TextNo
Value read from a JSON payloadNewtonsoft's parsed type — an ISO-8601 string in the payload arrives as a date; 03/09/2026 arrives as textYes for the former, no for the latter
Value read from SQLThe column's SQL typeYes

Always format your date placeholders

A DateTime with no format specifier renders through ToString(), which is culture-dependent and produces something like 3/9/2026 2:05:07 PM. That is almost never what an API filter wants. Write {SYS:DateLastPolled:O} or {SYS:DateLastPolled:yyyy-MM-ddTHH:mm:ssZ}, not {SYS:DateLastPolled}.

When the value is text and you need it formatted

Convert it to a real type first, then format. On the Transforms tab, chain a coercing transform ahead of the Formatting Template:

You haveChainResult
"2026-03-09T14:05:07Z" as textConvert TimeZone to UTCFormatting Template {0:yyyyMMdd}20260309
1430438400000 (epoch ms)From Epoch TimeFormatting Template {0:yyyy-MM-dd}2015-05-01
A timestamp you want as a bare dateDate OnlyFormatting Template {0:yyyy-MM-dd}2015-05-01

For a {VAR:...} placeholder there is no transform chain — set the Variable's Value Type to Date, Decimal, etc. and the format specifier starts working.

Where you can format

SurfaceSyntaxNotes
Parameterized placeholders — URLs, bodies, file names, instruction values, lookup templates{PREFIX:Name:format}The format is everything after the second colon, up to the closing brace
Formatting Template transform{0:format}, {1:format}, …Positional. {0} is the mapped value, or the first inner map of a multi-property map
Read URL and Read Body positional arguments{0:format}, {1:format}{0} is DateLastPolled, {1} is EventTime — see Positional arguments
Value Type (Advanced tab)dropdownConversion, not formatting — see Order of operations
Date Format (Read action)ISO / Unix Epoch MillisecondsApplies to the read-window date before it reaches any placeholder

Colons in a format are fine

The parser takes the first colon as the prefix separator and the second as the format separator; everything after that is the format. {SYS:EventTime:yyyy-MM-ddTHH:mm:ssZ} parses correctly.

Order of operations

Formatting is one step in a fixed chain. Getting the order wrong is the second most common cause of unexpected output.

On a property map (read or write):

  1. The raw value is read from the source (payload, column, or Common Model property).
  2. Transforms run in list order — including Formatting Template, which produces text.
  3. Value Type conversion runs after all transforms.
  4. The result is written.

Value Type undoes a Formatting Template

Because Value Type runs last, setting Value Type = Date on a map whose Formatting Template produced 03/09/2026 parses that text straight back into a DateTime and re-serializes it — discarding your formatting. If the Formatting Template is producing your final wire format, leave Value Type blank or set it to String.

On a Read URL or Read Body:

  1. {PREFIX:Name:format} placeholders are resolved and formatted.
  2. The resulting string is then run through positional string.Format with the read-window arguments.

Both passes see the same text, which is why brace escaping matters.

Date and time examples

Against 2026-03-09 14:05:07 UTC:

FormatOutputWhen to use
O2026-03-09T14:05:07.0000000ZRound-trip ISO 8601. The safest default, and what {SYS:CurrentDateTime} uses when you omit a format
s2026-03-09T14:05:07Sortable ISO without the zone — OData $filter, most REST query params
yyyy-MM-ddTHH:mm:ssZ2026-03-09T14:05:07ZISO with a literal Z. Use when the API rejects fractional seconds
yyyy-MM-ddTHH:mm:ss.fffZ2026-03-09T14:05:07.000ZISO with milliseconds only
yyyy-MM-dd2026-03-09Date-only filters, Salesforce/SuiteQL date literals
MM/dd/yyyy03/09/2026US-style APIs that insist on it
yyyyMMdd20260309File name stamps, fixed-width batch files
yyyyMMdd_HHmmss20260309_140507Unique file names per run
HH:mm:ss14:05:07Time-only fields
u2026-03-09 14:05:07ZUniversal sortable
RMon, 09 Mar 2026 14:05:07 GMTRFC 1123 — If-Modified-Since style headers
MMM d, yyyyMar 9, 2026Human-readable, e.g. a description field or an alert body

Worked examples:

/api/orders?modifiedSince={SYS:DateLastPolled:O}
/api/orders?$filter=lastmodifieddate ge {SYS:DateLastPolled:s}Z and lastmodifieddate lt {SYS:EventTime:s}Z
export_{SYS:CurrentDateTime:yyyyMMdd_HHmmss}.csv

Epoch timestamps

There is no format specifier for Unix time. Either set the read action's Date Format to Unix Epoch Milliseconds (which converts the read-window date before it is injected), or use the To Epoch Time transform on a map.

Time zones

Format strings render whatever instant they are given — they never shift it. To change the instant, use the Time Zone Conversion instruction (for the read-window timestamp) or the Convert UTC To TimeZone transform (for a mapped value), then format the result.

Number examples

FormatInputOutputWhen to use
0.003.53.50Fixed 2 decimals — money on the wire
F23.53.50Same, standard-specifier spelling
0.##3.503.5At most 2 decimals, trailing zeros dropped
D642000042Zero-padded integer (integers only)
00000042000042Zero-padded, works for any numeric type
#,##0.001234567.8911,234,567.89Grouped display value
P10.1515.0%Percentage — note it multiplies by 100
X255FFHexadecimal
0.00;(0.00);--12.3(12.30)Positive;negative;zero sections — accounting-style negatives

Culture-dependent specifiers

C (currency), N, P, D/d/g for dates, and anything relying on , or . as a separator render according to the server's culture, which you do not control per endpoint. For anything that goes on the wire, prefer an explicit custom format (0.00, #,##0.00, yyyy-MM-dd) over a standard specifier. Culture-dependent specifiers are fine for human-facing text such as alert bodies.

Decimals keep their scale

With no format specifier, a decimal renders with its stored scale — 3.50 stays 3.50, not 3.5. If a target rejects trailing zeros, format it explicitly with 0.##.

Composing values

The Formatting Template transform is the general-purpose "build a string" tool. On a multi-property map the inner maps arrive as {0}, {1}, {2} in the order they are listed; on a single-property map only {0} is available (and can be repeated).

TemplateInputOutput
{0} {1}John, DoeJohn Doe
{0}-{1}-{2}1, 2, 31-2-3
{2}, {1}, {0}1, 2, 33, 2, 1
{0}-TCFX-1234FX-1234-TC
INV-{0:D6}42INV-000042
{0:yyyy}-{0:MM}2026-03-09 (a date)2026-03
https://…/main.aspx?…&id={0}a GUIDa deep link into the source system

Notes:

  • A placeholder can be reused. {0}{0} is legal and repeats the value.
  • Alignment is supported: {0,10} right-aligns to 10 characters, {0,-10} left-aligns, {0,8:0.00} combines alignment and format. Useful for fixed-width file output.
  • A blank input short-circuits the transform — an empty or null value is returned unchanged rather than rendered into the template.
  • GUIDs honor {0:N} (no dashes) and {0:D} (with dashes).
  • To join a list into one delimited string, use the String Join transform, not a Formatting Template.

Escaping braces

Because Read URLs, Read Bodies, and save bodies are run through string.Format, a literal { or } in that text must be doubled. An unescaped brace that isn't a valid placeholder raises a FormatException and the action fails.

You want on the wireWrite
{'dateFilter': 1430438400000}{{'dateFilter': {0}}}
select * from {catalog}.{schema}select * from {{catalog}}.{{schema}}
{ orders(first: 50) { id } } (GraphQL){{ orders(first: 50) {{ id }} }}

This applies to any brace-heavy body — JSON, GraphQL, JSON-in-a-query-string. It does not apply to {PREFIX:Name} placeholders, which are resolved by the parameterizing pass and should be left single-braced.

TIP

It also applies to a Connector Property path that contains a literal brace, since list-index maps use the [{0}] pattern in that same field. A column genuinely named {ref} is written {{ref}}.

Troubleshooting

SymptomLikely cause
The value comes out exactly as it went in, format ignoredThe value is text. See The one rule — coerce it first
A date renders as 3/9/2026 2:05:07 PMNo format specifier on a DateTime placeholder; it fell back to culture-dependent ToString()
The Formatting Template output is discarded / re-serializedValue Type is set on the same map and runs after transforms — see Order of operations
FormatException / "Input string was not in a correct format" on a read or saveAn unescaped { or } in the URL or body — see Escaping braces
A Formatting Template errors on an indexThe template references {1} but the map supplies only one value; use a multi-property map
The placeholder renders as emptyThe token resolved to null — check the name and the prefix, not the format
The placeholder renders literally, braces and allThe prefix isn't recognized. Only SYS, PROP, CD, PK, FK, RD, SESSION, VAR, and AUTH are substituted
A format containing } doesn't workPlaceholder formats end at the first }. Use a Formatting Template transform instead

See Also

TeamCentral Admin Web Documentation