LocalDateToSystemDate
Converts a date in the account's configured time zone to the Marketing Cloud system date. Runtime-proven on a live Marketing Cloud Engagement CloudPage — including the fact that a date with no time part lands on the previous day.
Syntax
LocalDateToSystemDate(timeToConvert) → date
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
timeToConvert |
string | date | Yes | The local time value to convert, as a date value or a parseable date string |
Example
%%[
VAR @system
SET @system = LocalDateToSystemDate("2026-01-15 09:30:00")
]%%
%%=v(@system)=%%
Renders 1/15/2026 2:30:00 AM on the account this page was proven against — seven hours earlier than the input.
The usual reason to convert is to compare a user-supplied time against something the platform stamped in system time:
%%[
VAR @requested, @cutoff
SET @requested = LocalDateToSystemDate("2026-01-15 09:30:00")
SET @cutoff = DateAdd(Now(), 2, "H")
IF @requested > @cutoff THEN
]%%
<p>Scheduled.</p>
%%[ ELSE ]%%
<p>Too close to the cutoff.</p>
%%[ ENDIF ]%%
Pass a full timestamp, never a bare date — a date with no time is pushed into the previous day, see below.
Return value
date — a real date value, not text. FormatDate and DatePart 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 — 1/15/2026 2:30:00 AM.
Behaviour
The shift is not a fixed offset — it changes with the season. 2026-01-15 09:30:00 became 1/15/2026 2:30:00 AM, a DateDiff of -420 minutes, while 2026-07-15 09:30:00 became 7/15/2026 1:30:00 AM, -480 minutes. One hour further in summer, because system time is Central Standard with no daylight-saving adjustment while the account-configured local side observes it. Full write-up in the differs-from-docs card.
The account setting decides the result, not the viewer. The conversion uses the time zone configured on the account, so the result does not depend on where the page is being viewed from.
SystemDateToLocalDate is an exact inverse. Composing the two in either order returned the original instant with a DateDiff of 0, in both winter and summer — LocalDateToSystemDate(SystemDateToLocalDate("2026-07-15 09:30:00")) rendered 7/15/2026 9:30:00 AM, the input unchanged.
A date value can be passed in as well as a string. LocalDateToSystemDate(DateParse("2026-01-15 09:30:00")) produced the identical value as the string form, and LocalDateToSystemDate(Now()) converts the current instant directly. The US slash form parsed to the same value as the space-separated form.
An unreadable string takes the whole page down. "not a date at all" and an empty string both returned HTTP 422 with nothing rendered — the same failure mode as DateParse, not the empty string that FormatDate returns.
A date with no time lands on the previous day
A string carrying no time part is read as midnight, and subtracting the offset from midnight crosses back over the date boundary.
| Call | Renders |
|---|---|
LocalDateToSystemDate("2026-01-15") |
1/14/2026 5:00:00 PM |
LocalDateToSystemDate("2026-01-15 09:30:00") |
1/15/2026 2:30:00 AM |
Nothing aborts and nothing signals it, so code that formats only the date part afterwards reports the 14th for a value supplied as the 15th. The forward direction adds the offset instead and stays on the same day, which is why the trap is one-sided. Details in the differs-from-docs card.
Show test script
%%[
VAR @b, @w, @s
SET @b = RequestParameter("b")
SET @w = "2026-01-15 09:30:00"
SET @s = "2026-07-15 09:30:00"
/* the control - fetch this whenever a branch below renders nothing */
IF @b == "ctrl" THEN
OutputLine(Concat("--- ctrl start ---"))
OutputLine(Concat("CTRLS2L=[", SystemDateToLocalDate(@w), "]"))
OutputLine(Concat("CTRLL2S=[", LocalDateToSystemDate(@w), "]"))
OutputLine(Concat("--- ctrl done ---"))
ENDIF
/* the shift is seasonal - winter and summer differ by exactly one hour */
IF @b == "offset" THEN
OutputLine(Concat("--- offset start ---"))
OutputLine(Concat("WIN_IN=[", @w, "]"))
OutputLine(Concat("WIN_S2L=[", SystemDateToLocalDate(@w), "]"))
OutputLine(Concat("WIN_L2S=[", LocalDateToSystemDate(@w), "]"))
OutputLine(Concat("WIN_S2L_MIN=[", DateDiff(DateParse(@w), SystemDateToLocalDate(@w), "MI"), "]"))
OutputLine(Concat("WIN_L2S_MIN=[", DateDiff(DateParse(@w), LocalDateToSystemDate(@w), "MI"), "]"))
OutputLine(Concat("SUM_IN=[", @s, "]"))
OutputLine(Concat("SUM_S2L=[", SystemDateToLocalDate(@s), "]"))
OutputLine(Concat("SUM_L2S=[", LocalDateToSystemDate(@s), "]"))
OutputLine(Concat("SUM_S2L_MIN=[", DateDiff(DateParse(@s), SystemDateToLocalDate(@s), "MI"), "]"))
OutputLine(Concat("SUM_L2S_MIN=[", DateDiff(DateParse(@s), LocalDateToSystemDate(@s), "MI"), "]"))
OutputLine(Concat("--- offset done ---"))
ENDIF
/* both compositions return the original instant exactly */
IF @b == "rt" THEN
OutputLine(Concat("--- rt start ---"))
OutputLine(Concat("RT_W_A=[", SystemDateToLocalDate(LocalDateToSystemDate(@w)), "]"))
OutputLine(Concat("RT_W_B=[", LocalDateToSystemDate(SystemDateToLocalDate(@w)), "]"))
OutputLine(Concat("RT_S_A=[", SystemDateToLocalDate(LocalDateToSystemDate(@s)), "]"))
OutputLine(Concat("RT_S_B=[", LocalDateToSystemDate(SystemDateToLocalDate(@s)), "]"))
OutputLine(Concat("RT_W_A_MIN=[", DateDiff(DateParse(@w), SystemDateToLocalDate(LocalDateToSystemDate(@w)), "MI"), "]"))
OutputLine(Concat("RT_W_B_MIN=[", DateDiff(DateParse(@w), LocalDateToSystemDate(SystemDateToLocalDate(@w)), "MI"), "]"))
OutputLine(Concat("RT_S_A_MIN=[", DateDiff(DateParse(@s), SystemDateToLocalDate(LocalDateToSystemDate(@s)), "MI"), "]"))
OutputLine(Concat("RT_S_B_MIN=[", DateDiff(DateParse(@s), LocalDateToSystemDate(SystemDateToLocalDate(@s)), "MI"), "]"))
OutputLine(Concat("--- rt done ---"))
ENDIF
/* the result is a real date value the other date functions consume */
IF @b == "chain" THEN
OutputLine(Concat("--- chain start ---"))
OutputLine(Concat("S2L_FD=[", FormatDate(SystemDateToLocalDate(@w), "yyyy-MM-dd"), "]"))
OutputLine(Concat("L2S_FD=[", FormatDate(LocalDateToSystemDate(@w), "yyyy-MM-dd"), "]"))
OutputLine(Concat("S2L_PH=[", DatePart(SystemDateToLocalDate(@w), "H"), "]"))
OutputLine(Concat("L2S_PH=[", DatePart(LocalDateToSystemDate(@w), "H"), "]"))
OutputLine(Concat("S2L_PY=[", DatePart(SystemDateToLocalDate(@w), "Y"), "]"))
OutputLine(Concat("S2L_ADD=[", DateAdd(SystemDateToLocalDate(@w), 1, "D"), "]"))
OutputLine(Concat("S2L_LEN=[", Length(SystemDateToLocalDate(@w)), "]"))
OutputLine(Concat("L2S_LEN=[", Length(LocalDateToSystemDate(@w)), "]"))
OutputLine(Concat("--- chain done ---"))
ENDIF
/* a date value is accepted as well as a string */
IF @b == "dateval" THEN
OutputLine(Concat("--- dateval start ---"))
OutputLine(Concat("S2L_PARSED=[", SystemDateToLocalDate(DateParse(@w)), "]"))
OutputLine(Concat("L2S_PARSED=[", LocalDateToSystemDate(DateParse(@w)), "]"))
OutputLine(Concat("S2L_NOW=[", SystemDateToLocalDate(Now()), "]"))
OutputLine(Concat("L2S_NOW=[", LocalDateToSystemDate(Now()), "]"))
OutputLine(Concat("NOWRAW=[", Now(), "]"))
OutputLine(Concat("--- dateval done ---"))
ENDIF
/* several string notations, plus the date-only day-shift trap */
IF @b == "fmt" THEN
OutputLine(Concat("--- fmt start ---"))
OutputLine(Concat("S2L_DATEONLY=[", SystemDateToLocalDate("2026-01-15"), "]"))
OutputLine(Concat("L2S_DATEONLY=[", LocalDateToSystemDate("2026-01-15"), "]"))
OutputLine(Concat("S2L_US=[", SystemDateToLocalDate("1/15/2026 9:30 AM"), "]"))
OutputLine(Concat("L2S_US=[", LocalDateToSystemDate("1/15/2026 9:30 AM"), "]"))
OutputLine(Concat("S2L_ISOT=[", SystemDateToLocalDate("2026-01-15T09:30:00"), "]"))
OutputLine(Concat("--- fmt done ---"))
ENDIF
/* every branch below aborts the page - fetch them ONE at a time */
IF @b == "s2lbad" THEN
OutputLine(Concat("--- s2lbad start ---"))
OutputLine(Concat("S2LBAD=[", SystemDateToLocalDate("not a date at all"), "]"))
ENDIF
IF @b == "l2sbad" THEN
OutputLine(Concat("--- l2sbad start ---"))
OutputLine(Concat("L2SBAD=[", LocalDateToSystemDate("not a date at all"), "]"))
ENDIF
IF @b == "s2lempty" THEN
OutputLine(Concat("--- s2lempty start ---"))
OutputLine(Concat("S2LEMPTY=[", SystemDateToLocalDate(""), "]"))
ENDIF
IF @b == "l2sempty" THEN
OutputLine(Concat("--- l2sempty start ---"))
OutputLine(Concat("L2SEMPTY=[", LocalDateToSystemDate(""), "]"))
ENDIF
IF @b == "s2la0" THEN
OutputLine(Concat("--- s2la0 start ---"))
OutputLine(Concat("S2LA0=[", SystemDateToLocalDate(), "]"))
ENDIF
IF @b == "s2la2" THEN
OutputLine(Concat("--- s2la2 start ---"))
OutputLine(Concat("S2LA2=[", SystemDateToLocalDate(@w, 1), "]"))
ENDIF
IF @b == "l2sa0" THEN
OutputLine(Concat("--- l2sa0 start ---"))
OutputLine(Concat("L2SA0=[", LocalDateToSystemDate(), "]"))
ENDIF
IF @b == "l2sa2" THEN
OutputLine(Concat("--- l2sa2 start ---"))
OutputLine(Concat("L2SA2=[", LocalDateToSystemDate(@w, 1), "]"))
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("--- ctrl start ---")) — even for a single argument.
The -420 and -480 figures come from one business unit’s configured time zone. Re-running the script on another account gives different numbers; what stays true is the whole-hour shift and the one-hour gap between the winter and the summer measurement.
Availability
| Platform | Available |
|---|---|
| Marketing Cloud Engagement | Yes |
| Marketing Cloud Next | No |
See also
- SystemDateToLocalDate — the inverse conversion
- DateParse · FormatDate · DatePart — the functions that produce and consume the value
- Now — the system-time value this converts toward
- The differs-from-docs card — the seasonal shift and the date-only day shift
- Official reference · ampscript.guide