Coercions
The Coercions category holds functions that convert a value from one type to another: toString, toNumber, toDecimal, toBoolean, and the temporal four toDate, toDateTime, toLocalDateTime, and toTime. It also includes toJson for encoding a value as JSON text. Each is callable in prefix form fn(x, …) or postfix/UFCS form x fn(…).
These toX functions are a different mechanism from the as Type cast. They overlap in spirit but deliberately diverge in their edge cases: toString(null) is "" while null as String stays null, toNumber always yields a decimal while as Number preserves integers, and toBoolean never raises while as Boolean does. See Types and Coercion for the full picture of all four coercion mechanisms (truthiness, as Type, these toX functions, and operator coercion), and the toX vs as Type callout below for the specifics.
Scalar Coercions
These four convert to String, Number, Boolean. Cells use → for results.
| Function | Signature | Description | Example |
|---|---|---|---|
toString | (:any) | Stringifies the value. null becomes the empty string. Arrays and objects use native rendering, not JSON. | toString(42.5) → "42.5"; toString(null) → "" |
toNumber | (:any) | Parses to a decimal Number (always, even for whole values). Accepts numeric strings, numbers, and booleans (true → 1.0, false → 0.0). Raises on non-numeric strings and on null. No grouping separators. | toNumber("42") → 42.0; toNumber(true) → 1.0 |
toDecimal | (:any) | Parses to an exact decimal Number from a Number or numeric string. Raises on booleans, null, and non-numeric strings. | toDecimal("3.14") → 3.14; toDecimal(42) → 42 |
toBoolean | (:any) | Converts to a Boolean and never raises. Recognizes (trimmed, case-insensitive) true/1/yes → true and false/0/no → false; any other value falls back to truthiness, where only false and null are falsy. | toBoolean("yes") → true; toBoolean(0) → false; toBoolean("maybe") → true |
A few details to keep in mind:
toNumberreturns aNumberwhose value is always a float —toNumber("42")is42.0, never the integer42.toDecimalreturns aNumbertoo, but does not force a fractional form (toDecimal(42)→42).toBooleanfalls back to plain truthiness, sotoBoolean("maybe"),toBoolean(""), andtoBoolean(5)are alltrue; only the recognized false-words,false,null, and0/0.0arefalse.toStringon a Number, Boolean, Array, or Object uses native rendering (e.g.toString([1, 2, 3])→"[1, 2, 3]"). It is not JSON encoding; usetoJsonto produce JSON text.
JSON Serialization
toJson(:any) accepts any value and returns a String containing its JSON representation. Use it when a field must contain JSON text, including nested Arrays and Objects. The output json directive serializes the whole script result; toJson produces a String that you can include within that result.
JSON encoding adds quotes around a String and escapes quotes, backslashes, and newlines inside it. It preserves Numbers, Booleans, and null values within collections. Unlike toString(null), which returns "", toJson(null) returns the four-character String "null".
toJson("report") // → "\"report\""
toJson("first\n\"second\"") // → "\"first\\n\\\"second\\\"\""
toJson({ name: "report", items: [3, null, true] })
// → "{\"name\":\"report\",\"items\":[3,null,true]}"
toJson(null) // → "null"
The result is JSON text, not an Object or Array. Invalid text encoding or a value that JSON cannot represent raises a serialization error.
Temporal Coercions
The four temporal coercions accept temporal literals (written with |…|), other temporal values, and strings.
Two of them take an optional strptime format string as the second argument; the other two take an optional time zone. They are not interchangeable.
TransformScript's reference time zone is UTC in every execution context. When a calculation needs a particular business time zone, convert the instant to that zone before extracting its date. For example, toDate(toDateTime(|2024-05-01T02:00:00Z|, "America/New_York")) returns |2024-04-30|, because it is still April 30 there.
toDate(:any, :string?) — Second Arg Is a strptime Format
Returns a Date (calendar date, no time). Accepts a Date, a DateTime, a LocalDateTime, or a string. With a second argument, the string is parsed with that strptime format.
toDate("2024-05-01") → |2024-05-01|
toDate(|2024-05-01T23:57:59-07:00|) → |2024-05-01|
toDate("05/01/2024", "%m/%d/%Y") → |2024-05-01|
toTime(:any, :string?) — Second Arg Is a strptime Format
Despite the name, toTime returns a DateTime (a full zoned instant), not a bare time-of-day. It accepts a Date, a DateTime, or a string. A Date becomes midnight UTC, and an existing DateTime keeps its zone. Strings without a format are parsed in UTC; an offset in the string determines the instant. The optional second argument supplies a strptime format. When a string supplies only a time, its date defaults to the current date in UTC. A formatted string without an offset uses UTC.
toTime("2024-05-01T13:30:00") → |2024-05-01T13:30:00Z|
toTime("11:30 PM", "%I:%M %p") → a DateTime at 23:30:00 on today's UTC date
toTime("23:57:59") → a DateTime at 23:57:59 on today's UTC date
toTime(|23:57:59|) → raises (a LocalTime value is not accepted)
toDateTime(:any, :string?) — Second Arg Is a Time Zone
Returns a DateTime (zoned instant). Accepts a temporal value or an ISO-8601 string. The optional second argument is a time zone name; when given, the result is shifted into that zone.
toDateTime("2024-05-01T12:00:00Z") → |2024-05-01T12:00:00Z|
toDateTime(|2020-10-01T23:57:59-07:00|) → |2020-10-01T23:57:59-07:00|
toDateTime("2024-05-01T12:00:00Z", "America/New_York") → |2024-05-01T08:00:00-04:00|
toLocalDateTime(:any, :string?) — Second Arg Is a Time Zone
Returns a LocalDateTime (date + time, no zone). Accepts a temporal value or string. A LocalDateTime passes through unchanged when no zone is given. The optional second argument is a time zone: the instant is first shifted into that zone, then the zone is dropped, so the wall-clock fields reflect that zone.
toLocalDateTime(|2020-10-01T23:57:59-07:00|) → |2020-10-01T23:57:59|
toLocalDateTime("2024-05-01T12:00:00Z") → |2024-05-01T12:00:00|
toLocalDateTime("2024-05-01T12:00:00Z", "Europe/Paris") → |2024-05-01T14:00:00|
toX vs as Type
The toX functions and the as Type cast are separate mechanisms:
| Input | toX result | as Type result |
|---|---|---|
null to String | toString(null) → "" | null as String → null |
"42" to Number | toNumber("42") → 42.0 (decimal) | "42" as Number → 42 (integer preserved) |
"maybe" to Boolean | toBoolean("maybe") → true (truthiness fallback) | "maybe" as Boolean → raises Unable to interpret 'maybe' as Boolean |
"yes" to Boolean | toBoolean("yes") → true | "yes" as Boolean → true |
Rules of thumb:
toStringis total;as Stringpreservesnull. Reach fortoStringwhen you want a guaranteed string (empty fornull); useas Stringwhennullmust staynull, or when you need formatting options (format,timeZone) or JSON-encoded collections.toNumberalways returns a decimal;as Numberpreserves integers and supports locale/separator options. UsetoDecimalfor an exact decimal that does not force a fractional form. NeithertoNumbernortoDecimalaccepts grouping separators (toNumber("1,000")raises);as NumberwithgroupingSeparatordoes.toBooleannever raises;as Booleandoes.toBooleanrecognizes1/yes/0/noand otherwise falls back to truthiness.as Booleanaccepts a fixed vocabulary and raises on anything outside it (customizable withtrueValues/falseValues).- Argument shapes differ across temporal coercions.
toDateandtoTimetake an optional strptime format;toDateTimeandtoLocalDateTimetake an optional time zone. (toTimereturns aDateTime, not aLocalTime.)
Related
- Types and Coercion — the four coercion mechanisms and how they differ.
- Types — the
is…Typereflection predicates andtypeOf. - Dates and Times — temporal constructors and truncation helpers.
- Function Library — all categories.