DateParse
Parses a date string into a date value. Runtime-proven on a live Marketing Cloud Engagement CloudPage — including the fact that a day-first date is silently read month-first while an unreadable one takes the whole page down.
Syntax
DateParse(dateString[, useUtc]) → date
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
dateString |
string | date | Yes | A date or timestamp string, or an existing date value |
useUtc |
string | boolean | number | No | Whether to return the instant in UTC instead of the account time zone; defaults to off |
Example
%%[
VAR @parsed
SET @parsed = DateParse("2026-03-04T09:05:07")
]%%
%%=v(@parsed)=%%
Renders 3/4/2026 9:05:07 AM.
The value is a real date, so the point of parsing is usually to hand it straight to another date function:
%%[
VAR @raw, @due
SET @raw = "2026-03-04"
SET @due = FormatDate(DateAdd(DateParse(@raw), 30, "D"), "yyyy-MM-dd")
]%%
<p>Payment due %%=v(@due)=%%</p>
Only pass a string you control the shape of — an unreadable one discards the whole page, and a day-first one is misread rather than refused. Both are covered below.
Return value
date — a real date value, not text. DatePart, FormatDate, DateAdd and DateDiff all accepted the result directly, and Length() over it returned 20.
There is no closed set of sentinel values to test for, and no failure value either. Every rejected input aborts the page with HTTP 422 rather than returning an error token, so a result that exists is always a real date.
Rendered on its own the value prints as a US short date followed by a 12-hour clock with an AM/PM suffix — 3/4/2026 12:00:00 AM for a date with no time part.
Behaviour
The second argument really does change the value, unlike the flag on Now. Parsing 2026-03-04 09:05:07 with the flag off gave 3/4/2026 9:05:07 AM and with it on gave 3/4/2026 3:05:07 PM — a DateDiff of exactly 6 hours, the account’s offset from UTC. Every spelling is accepted interchangeably: 1/0, true/false, and all four of those quoted, each producing the identical instant as its counterpart. The argument is not validated either — passing the word spring was accepted and behaved as the off path.
A timezone offset in the input is honoured, not discarded. 2026-03-04T09:05:07+02:00 came back as 1:05:07 AM and a Z-suffixed Zulu timestamp as 3:05:07 AM, both correctly converted into the account zone. An RFC-style string ending in GMT converted the same way.
A time with no date borrows the day of the render. 1:41 PM parsed successfully and took today’s date, so it is the one accepted form whose result is not deterministic from the input alone.
An existing date value can be passed straight back in. DateParse(Now()) returned the same instant, which is what makes the UTC conversion idiom DateParse(Now(), 1) work without any string round-trip.
Which input formats parse
Fixed inputs, each proven in its own gate.
| Call | Renders |
|---|---|
DateParse("2026-03-04") |
3/4/2026 12:00:00 AM |
DateParse("2026-03-04 09:05:07") |
3/4/2026 9:05:07 AM |
DateParse("2026-03-04T09:05:07") |
3/4/2026 9:05:07 AM |
DateParse("2026-03-04T09:05:07+02:00") |
3/4/2026 1:05:07 AM |
DateParse("3/4/2026 9:05 AM") |
3/4/2026 9:05:00 AM |
DateParse("4 March 2026") |
3/4/2026 12:00:00 AM |
DateParse("March 4, 2026") |
3/4/2026 12:00:00 AM |
DateParse("Wed, 04 Mar 2026 09:05:07 GMT") |
3/4/2026 3:05:07 AM |
DateParse("1:41 PM") |
today’s date at 1:41:00 PM |
An ordinal-suffixed day, a non-English month name, free text, an empty string, an epoch-like numeric string such as "1772614800" and a bare number such as 20260304 all abort the page instead. There is no numeric input path at all, and no return value to test for afterwards — see the differs-from-docs card.
A day-first date is misread, not refused
5/8/2026 meant as the 5th of August parsed cleanly and came back as 5/8/2026 12:00:00 AM — the 8th of May. Nothing aborts and nothing signals the problem, so a European-formatted feed produces plausible dates that are months wrong. Normalise to yyyy-MM-dd before parsing. Full write-up in the differs-from-docs card.
Show test script
%%[
VAR @b, @s, @iso, @isot
SET @b = RequestParameter("b")
SET @s = "2026-03-04 09:05:07"
SET @iso = "2026-03-04"
SET @isot = "2026-03-04T09:05:07"
/* the control - fetch this whenever a branch below renders nothing */
IF @b == "ctrl" THEN
OutputLine(Concat("--- ctrl start ---"))
OutputLine(Concat("CTRL=[", DateParse(@iso, 0), "]"))
OutputLine(Concat("--- ctrl done ---"))
ENDIF
/* the input formats that parse */
IF @b == "formats" THEN
OutputLine(Concat("--- formats start ---"))
OutputLine(Concat("DATETIME=[", DateParse(@s), "]"))
OutputLine(Concat("ISO=[", DateParse(@iso), "]"))
OutputLine(Concat("ISOT=[", DateParse(@isot), "]"))
OutputLine(Concat("ISOTZ=[", DateParse("2026-03-04T09:05:07-06:00"), "]"))
OutputLine(Concat("US=[", DateParse("3/4/2026 9:05 AM"), "]"))
OutputLine(Concat("WORDA=[", DateParse("4 March 2026"), "]"))
OutputLine(Concat("WORDB=[", DateParse("March 4, 2026"), "]"))
OutputLine(Concat("DTAMPM=[", DateParse("2026-03-04 9:05:07 AM"), "]"))
OutputLine(Concat("RFC=[", DateParse("Wed, 04 Mar 2026 09:05:07 GMT"), "]"))
OutputLine(Concat("--- formats done ---"))
ENDIF
/* the flag shifts the instant by the account's offset from UTC */
IF @b == "utc" THEN
OutputLine(Concat("--- utc start ---"))
OutputLine(Concat("U0=[", DateParse(@s, 0), "]"))
OutputLine(Concat("U1=[", DateParse(@s, 1), "]"))
OutputLine(Concat("UDIFF=[", DateDiff(DateParse(@s, 0), DateParse(@s, 1), "H"), "]"))
OutputLine(Concat("NOWRAW=[", Now(), "]"))
OutputLine(Concat("NOWUTC=[", DateParse(Now(), 1), "]"))
OutputLine(Concat("--- utc done ---"))
ENDIF
/* every spelling of the flag, number, boolean and quoted alike */
IF @b == "flags" THEN
OutputLine(Concat("--- flags start ---"))
OutputLine(Concat("BT=[", DateParse(@s, true), "]"))
OutputLine(Concat("BF=[", DateParse(@s, false), "]"))
OutputLine(Concat("S1=[", DateParse(@s, "1"), "]"))
OutputLine(Concat("S0=[", DateParse(@s, "0"), "]"))
OutputLine(Concat("STRUE=[", DateParse(@s, "true"), "]"))
OutputLine(Concat("SFALSE=[", DateParse(@s, "false"), "]"))
OutputLine(Concat("--- flags done ---"))
ENDIF
/* an offset in the input is converted, not dropped */
IF @b == "tzoff" THEN
OutputLine(Concat("--- tzoff start ---"))
OutputLine(Concat("PLUS2=[", DateParse("2026-03-04T09:05:07+02:00"), "]"))
OutputLine(Concat("PLUS2U=[", DateParse("2026-03-04T09:05:07+02:00", 1), "]"))
OutputLine(Concat("ZULU=[", DateParse("2026-03-04T09:05:07Z"), "]"))
OutputLine(Concat("ZULUU=[", DateParse("2026-03-04T09:05:07Z", 1), "]"))
OutputLine(Concat("--- tzoff done ---"))
ENDIF
/* the result is a real date value the other date functions consume */
IF @b == "chain" THEN
OutputLine(Concat("--- chain start ---"))
OutputLine(Concat("PY=[", DatePart(DateParse(@isot), "Y"), "]"))
OutputLine(Concat("PMI=[", DatePart(DateParse(@isot), "MI"), "]"))
OutputLine(Concat("FD=[", FormatDate(DateParse(@isot), "yyyy-MM-dd"), "]"))
OutputLine(Concat("DA=[", DateAdd(DateParse(@iso), 1, "D"), "]"))
OutputLine(Concat("DD=[", DateDiff(DateParse(@iso), DateParse("2026-03-06"), "D"), "]"))
OutputLine(Concat("LEN=[", Length(DateParse(@iso)), "]"))
OutputLine(Concat("--- chain done ---"))
ENDIF
/* a time with no date borrows the day of the render */
IF @b == "timeonly" THEN
OutputLine(Concat("--- timeonly start ---"))
OutputLine(Concat("TIMEONLY=[", DateParse("1:41 PM"), "]"))
OutputLine(Concat("--- timeonly done ---"))
ENDIF
/* a day-first date is misread rather than refused */
IF @b == "little" THEN
OutputLine(Concat("--- little start ---"))
OutputLine(Concat("MEANT_5_AUGUST=[", DateParse("5/8/2026"), "]"))
OutputLine(Concat("ISO_CONTROL=[", DateParse("2026-08-05"), "]"))
OutputLine(Concat("--- little done ---"))
ENDIF
/* the flag is not validated */
IF @b == "badflag" THEN
OutputLine(Concat("--- badflag start ---"))
OutputLine(Concat("BADFLAG=[", DateParse(@s, "spring"), "]"))
OutputLine(Concat("--- badflag done ---"))
ENDIF
/* an existing date value is accepted in the first position */
IF @b == "dateval" THEN
OutputLine(Concat("--- dateval start ---"))
OutputLine(Concat("DATEVAL=[", DateParse(Now()), "]"))
OutputLine(Concat("--- dateval done ---"))
ENDIF
/* every branch below aborts the page - fetch them ONE at a time */
IF @b == "ordinal" THEN
OutputLine(Concat("--- ordinal start ---"))
OutputLine(Concat("ORDINAL=[", DateParse("March 4th, 2026"), "]"))
ENDIF
IF @b == "frmonth" THEN
OutputLine(Concat("--- frmonth start ---"))
OutputLine(Concat("FRMONTH=[", DateParse("4 mai 2026"), "]"))
ENDIF
IF @b == "epoch" THEN
OutputLine(Concat("--- epoch start ---"))
OutputLine(Concat("EPOCH=[", DateParse("1772614800"), "]"))
ENDIF
IF @b == "numdate" THEN
OutputLine(Concat("--- numdate start ---"))
OutputLine(Concat("NUMDATE=[", DateParse(20260304), "]"))
ENDIF
IF @b == "baddate" THEN
OutputLine(Concat("--- baddate start ---"))
OutputLine(Concat("BADDATE=[", DateParse("not a date at all"), "]"))
ENDIF
IF @b == "emptydate" THEN
OutputLine(Concat("--- emptydate start ---"))
OutputLine(Concat("EMPTYDATE=[", DateParse(""), "]"))
ENDIF
IF @b == "a0" THEN
OutputLine(Concat("--- a0 start ---"))
OutputLine(Concat("A0=[", DateParse(), "]"))
ENDIF
IF @b == "a3" THEN
OutputLine(Concat("--- a3 start ---"))
OutputLine(Concat("A3=[", DateParse(@s, 1, "extra"), "]"))
ENDIF
]%%
A bare string literal passed to OutputLine renders an empty line while the page still returns HTTP 200, so the marker silently vanishes and the block looks like a function that produced no output. Always wrap it — OutputLine(Concat("--- safe start ---")) — even for a single argument.
AMPscript has no try/catch, so an unreadable date string aborts the render and throws away everything already written above it. When testing, put each risky call behind its own RequestParameter branch and fetch them one at a time — otherwise a single failure hides every result on the page.
Availability
| Platform | Available |
|---|---|
| Marketing Cloud Engagement | Yes |
| Marketing Cloud Next | Yes, from API 67.0 |
Everything on this page was proven on an Engagement CloudPage. The official reference states that on Marketing Cloud Next the function returns a locale-formatted string rather than a date value, which would break the chaining shown above; that claim was not tested here.
See also
- FormatDate — the usual next call, and the recommended alternative on Marketing Cloud Next
- DateAdd · DateDiff · DatePart — the functions that consume the parsed value
- Now — whose own optional flag, unlike this one, changes nothing on a CloudPage
- The differs-from-docs cards — the page abort and the day-first misreading
- Official reference · ampscript.guide