Runtime verified Test scripts included

Syntax

StringToDate(dateString)  →  date
1 argument — exactly

Parameters

Name Type Required Description
dateString string | date Yes A date or timestamp string, or an existing date value

Example

%%[
  VAR @parsed
  SET @parsed = StringToDate("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(StringToDate(@raw), 30, "D"), "yyyy-MM-dd")
]%%
<p>Payment due %%=v(@due)=%%</p>

If a UTC conversion might ever be needed, reach for DateParse instead — this name has no second argument to ask for one.

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.

It behaves exactly like DateParse

Both functions were called on the same line of the same render, against the same fixed inputs. Every pair matched character for character.

Call StringToDate renders DateParse renders
("2026-03-04") 3/4/2026 12:00:00 AM 3/4/2026 12:00:00 AM
("2026-03-04 09:05:07") 3/4/2026 9:05:07 AM 3/4/2026 9:05:07 AM
("2026-03-04T09:05:07") 3/4/2026 9:05:07 AM 3/4/2026 9:05:07 AM
("2026-03-04T09:05:07+02:00") 3/4/2026 1:05:07 AM 3/4/2026 1:05:07 AM
("2026-03-04T09:05:07Z") 3/4/2026 3:05:07 AM 3/4/2026 3:05:07 AM
("3/4/2026 9:05 AM") 3/4/2026 9:05:00 AM 3/4/2026 9:05:00 AM
("4 March 2026") 3/4/2026 12:00:00 AM 3/4/2026 12:00:00 AM
("March 4, 2026") 3/4/2026 12:00:00 AM 3/4/2026 12:00:00 AM
("Wed, 04 Mar 2026 09:05:07 GMT") 3/4/2026 3:05:07 AM 3/4/2026 3:05:07 AM

Measured rather than eyeballed: a DateDiff in hours between the two results over the same input returned 0, and Length() over each returned 20.

The one real difference is arity. DateParse takes an optional second argument that returns the instant in UTC. StringToDate accepts exactly one argument — passing that same flag shape aborts the page, and so does the "UTF-8" encoding argument some community references still list for it. Neither is ignored; both are rejected. The relationship is written up in the differs-from-docs card.

Behaviour

The failure mode is shared too, and it is the harsh one. Free text, an empty string and a bare number such as 20260304 each abort the render with HTTP 422 and discard everything already written above them — under either name. There is no value to inspect afterwards, so validate the string before the call rather than checking the result.

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. StringToDate(Now()) returned the current instant unchanged, so the parameter accepts a date as well as a string.

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. The same input misreads identically under DateParse; full write-up in that function’s 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("CTRLSD=[", StringToDate(@iso), "]"))
    OutputLine(Concat("CTRLDP=[", DateParse(@iso), "]"))
    OutputLine(Concat("--- ctrl done ---"))
  ENDIF

  /* every accepted format, next to the DateParse result for the same input */
  IF @b == "formats" THEN
    OutputLine(Concat("--- formats start ---"))
    OutputLine(Concat("ISO_S=[", StringToDate(@iso), "] ISO_D=[", DateParse(@iso), "]"))
    OutputLine(Concat("DT_S=[", StringToDate(@s), "] DT_D=[", DateParse(@s), "]"))
    OutputLine(Concat("ISOT_S=[", StringToDate(@isot), "] ISOT_D=[", DateParse(@isot), "]"))
    OutputLine(Concat("US_S=[", StringToDate("3/4/2026 9:05 AM"), "] US_D=[", DateParse("3/4/2026 9:05 AM"), "]"))
    OutputLine(Concat("WA_S=[", StringToDate("4 March 2026"), "] WA_D=[", DateParse("4 March 2026"), "]"))
    OutputLine(Concat("WB_S=[", StringToDate("March 4, 2026"), "] WB_D=[", DateParse("March 4, 2026"), "]"))
    OutputLine(Concat("TZ_S=[", StringToDate("2026-03-04T09:05:07+02:00"), "] TZ_D=[", DateParse("2026-03-04T09:05:07+02:00"), "]"))
    OutputLine(Concat("Z_S=[", StringToDate("2026-03-04T09:05:07Z"), "] Z_D=[", DateParse("2026-03-04T09:05:07Z"), "]"))
    OutputLine(Concat("RFC_S=[", StringToDate("Wed, 04 Mar 2026 09:05:07 GMT"), "] RFC_D=[", DateParse("Wed, 04 Mar 2026 09:05:07 GMT"), "]"))
    OutputLine(Concat("LEN_S=[", Length(StringToDate(@iso)), "] LEN_D=[", Length(DateParse(@iso)), "]"))
    OutputLine(Concat("--- formats 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(StringToDate(@isot), "Y"), "]"))
    OutputLine(Concat("PMI=[", DatePart(StringToDate(@isot), "MI"), "]"))
    OutputLine(Concat("FD=[", FormatDate(StringToDate(@isot), "yyyy-MM-dd"), "]"))
    OutputLine(Concat("DA=[", DateAdd(StringToDate(@iso), 1, "D"), "]"))
    OutputLine(Concat("DD=[", DateDiff(StringToDate(@iso), StringToDate("2026-03-06"), "D"), "]"))
    OutputLine(Concat("XDIFF=[", DateDiff(StringToDate(@s), DateParse(@s), "H"), "]"))
    OutputLine(Concat("--- chain done ---"))
  ENDIF

  /* a day-first date is misread rather than refused, under both names */
  IF @b == "little" THEN
    OutputLine(Concat("--- little start ---"))
    OutputLine(Concat("MEANT_5_AUGUST_S=[", StringToDate("5/8/2026"), "]"))
    OutputLine(Concat("MEANT_5_AUGUST_D=[", DateParse("5/8/2026"), "]"))
    OutputLine(Concat("ISO_CONTROL=[", StringToDate("2026-08-05"), "]"))
    OutputLine(Concat("--- little done ---"))
  ENDIF

  /* a time with no date borrows the day of the render */
  IF @b == "timeonly" THEN
    OutputLine(Concat("--- timeonly start ---"))
    OutputLine(Concat("TO_S=[", StringToDate("1:41 PM"), "] TO_D=[", DateParse("1:41 PM"), "]"))
    OutputLine(Concat("--- timeonly done ---"))
  ENDIF

  /* an existing date value is accepted, not just a string */
  IF @b == "dateval" THEN
    OutputLine(Concat("--- dateval start ---"))
    OutputLine(Concat("DV=[", StringToDate(Now()), "]"))
    OutputLine(Concat("--- dateval done ---"))
  ENDIF

  /* every branch below aborts the page - fetch them ONE at a time */
  IF @b == "a0" THEN
    OutputLine(Concat("--- a0 start ---"))
    OutputLine(Concat("A0=[", StringToDate(), "]"))
  ENDIF

  /* the encoding argument some references list is rejected, not ignored */
  IF @b == "a2enc" THEN
    OutputLine(Concat("--- a2enc start ---"))
    OutputLine(Concat("A2ENC=[", StringToDate(@s, "UTF-8"), "]"))
  ENDIF

  /* the DateParse UTC flag has no counterpart here */
  IF @b == "a2flag" THEN
    OutputLine(Concat("--- a2flag start ---"))
    OutputLine(Concat("A2FLAG=[", StringToDate(@s, 1), "]"))
  ENDIF

  IF @b == "a3" THEN
    OutputLine(Concat("--- a3 start ---"))
    OutputLine(Concat("A3=[", StringToDate(@s, 1, "extra"), "]"))
  ENDIF

  IF @b == "bad" THEN
    OutputLine(Concat("--- bad start ---"))
    OutputLine(Concat("BAD=[", StringToDate("not a date at all"), "]"))
  ENDIF

  IF @b == "empty" THEN
    OutputLine(Concat("--- empty start ---"))
    OutputLine(Concat("EMPTY=[", StringToDate(""), "]"))
  ENDIF

  IF @b == "num" THEN
    OutputLine(Concat("--- num start ---"))
    OutputLine(Concat("NUM=[", StringToDate(20260304), "]"))
  ENDIF
]%%

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