Funciones de fecha — Referencia de SSJS en Marketing Cloud
Manejo de fecha y hora en SSJS — Now / DateAdd / DateDiff / DatePart más los métodos del objeto Date nativo de JavaScript (era ES5). Misma trampa de UTC que SQL, más los códigos string de date-part que tenés que memorizar.
Las fechas en SSJS vienen de tres fuentes: el helper global Now(), el constructor nativo Date de JavaScript, y las funciones SSJS-específicas DateAdd / DateDiff / DatePart. Las trampas son familiares de la superficie SQL — Now() es UTC sin importar el timezone local de tu tenant, la aritmética por mes es inestable en los límites, y tenés que conocer los códigos crípticos de date-part ("y", "m", "d", "h", "n", "s") como conocerías DATEPART(year, ...) en SQL.
Sintaxis oficial
Los helpers SSJS-nativos (no necesitan prefijo Platform.Function.):
Platform.Load("Core", "1.1.5");
// Timestamp actual — UTC, NO el horario local de tu tenant
var now = Now();
// → Objeto Date representando el momento actual en UTC
// Constructor de Date nativo de JS (también UTC-based por default)
var specific = new Date("2026-05-08T14:23:11Z");
var fromMs = new Date(1746724991000);
var pieces = new Date(2026, 4, 8, 14, 23, 11); // year, monthIndex (0-based!), day, h, m, s
// === Aritmética de fecha SSJS-específica ===
// DateAdd(start, interval, datePart)
DateAdd(Now(), -90, "d"); // 90 días atrás
DateAdd(Now(), 12, "h"); // 12 horas en el futuro
DateAdd(Now(), -3, "m"); // 3 meses atrás — inestable en los límites
// DateDiff(start, end, datePart)
DateDiff(Now(), DateAdd(Now(), 90, "d"), "d"); // → 90
DateDiff(lastPurchase, Now(), "d"); // días desde la última compra
// DatePart(date, datePart) — devuelve entero
DatePart(Now(), "y"); // → 2026
DatePart(Now(), "m"); // → 5 (NO 0-based; este es el mes calendario)
DatePart(Now(), "d"); // → 8
DatePart(Now(), "h"); // → 14 (hora UTC)
DatePart(Now(), "n"); // → 23 (minuto — ¡NO "m"!)
DatePart(Now(), "s"); // → 11
// === FormatDate (cubierto en String functions, repetido por contexto) ===
Platform.Function.FormatDate(Now(), "yyyy-MM-dd HH:mm:ss", "en-US");
// → "2026-05-08 14:23:11"
// === Métodos nativos de Date de JS ===
var d = Now();
d.getFullYear(); // → 2026
d.getMonth(); // → 4 (0-indexado; Enero = 0)
d.getDate(); // → 8 (día del mes)
d.getDay(); // → 4 (día de la semana, 0 = Domingo)
d.getHours(); // → 14 (hora UTC)
d.getMinutes(); // → 23
d.getTime(); // → 1746724991000 (ms desde el epoch)
d.toISOString(); // → "2026-05-08T14:23:11.000Z"Los códigos string datePart (usados por DateAdd / DateDiff / DatePart):
| Código | Significa |
|---|---|
| "y" | Año |
| "m" | Mes |
| "d" | Día |
| "h" | Hora |
| "n" | Minuto (no "m" — eso es mes) |
| "s" | Segundo |
| "q" | Cuarto (Quarter) |
| "w" | Semana |
| Función | Devuelve | Notas |
|---|---|---|
| Now() | Objeto Date | Momento UTC actual |
| DateAdd(date, n, part) | Date | Suma n de part a date |
| DateDiff(start, end, part) | Entero | Diferencia en unidades enteras de part |
| DatePart(date, part) | Entero | Extrae parte calendario de date |
| new Date() | Date | Momento actual (igual que Now() en la práctica) |
| new Date(year, mon, day, ...) | Date | Constructor con mes 0-indexado |
| new Date(isoString) | Date | Parseado desde string ISO 8601 |
| new Date(ms) | Date | Desde milisegundos desde el epoch |
| Platform.Function.FormatDate(d, fmt, loc) | String | Formateo locale-aware |
| Platform.Function.SystemDateToLocalDate(d) | Date | UTC → local basado en setting de timezone del tenant |
Referencia:
- Salesforce Developer — Referencia de Platform Functions (helpers de fecha) ↗
- MDN — Referencia del objeto Date (filtrá a ES5 / pre-2010 para SSJS) ↗
Lo que sobrevive en producción
Now() es UTC, no el horario local de tu tenant
Misma trampa que el GETDATE() de SQL. Los scripts SSJS que hacen "send entre 9am y 6pm hora Buenos Aires" usando Now() crudo van a dispararse a las horas locales equivocadas.
// EN RIESGO — chequea hora UTC, dispara a hora local equivocada
var hour = DatePart(Now(), "h");
if (hour >= 9 && hour <= 18) {
// ...
}
// CORRECTO — convertí a local primero
var hour = DatePart(DateAdd(Now(), -3, "h"), "h"); // ART = UTC-3
if (hour >= 9 && hour <= 18) {
// ...
}
// MEJOR — usá SystemDateToLocalDate que honra el timezone configurado
// del tenant (DST-aware)
var localNow = Platform.Function.SystemDateToLocalDate(Now());
var hour = DatePart(localNow, "h");SystemDateToLocalDate es la respuesta correcta en contextos multi-BU o DST-sensitive porque lee el timezone configurado del tenant en lugar de hardcodear un offset que se rompe en los límites de DST.
DateAdd(date, n, "m") (meses) es inestable en los límites de mes
Igual que el DATEADD(month, ...) de SQL — sumar/restar meses de una fecha que no tiene contraparte en el mes destino produce resultados engine-dependent (Feb 28 vs Feb 29, May 31 → Feb 28, etc.).
// EN RIESGO — math de meses, edge cases en límites de año
var threeMonthsAgo = DateAdd(Now(), -3, "m");
// ESTABLE — math de conteo de días, se comporta igual cada corrida
var ninetyDaysAgo = DateAdd(Now(), -90, "d");Si la regla de negocio es "últimos 3 meses", traducí a un conteo de días una vez en momento de diseño y documentá la conversión en un comentario. Ver gotchas SSJS (cross-aplica la misma disciplina del #8 SQL).
DatePart(date, "n") para minutos — el críptico
La convención de naming no es intuitiva. Mes es "m", minuto es "n". Usar "m" cuando querías decir "n" devuelve el número de mes cuando querías el minuto. El error es silencioso porque el script corre y devuelve un entero válido, solo el equivocado.
// BUG — "m" devuelve número de mes (1-12), no minuto (0-59)
var mins = DatePart(Now(), "m");
// A las 14:23 en mayo, devuelve 5, no 23.
// CORRECTO
var mins = DatePart(Now(), "n");Memorizá la tabla o copiá desde un snippet — no trates de adivinar.
new Date(year, month, ...) nativo usa mes 0-indexado; DatePart y FormatDate usan 1-indexado
Este es el bug de fecha SSJS más común en Cleon. El constructor JS nativo trata 0 como Enero, 11 como Diciembre. DatePart(d, "m") devuelve 1 para Enero, 12 para Diciembre. FormatDate(d, "MM") igualmente devuelve 01 para Enero.
// EN RIESGO — el constructor espera monthIndex (0-based)
var jan = new Date(2026, 1, 15); // → Febrero 15, NO Enero 15
var dec = new Date(2026, 12, 15); // → Enero 15, 2027 (¡rolls over!)
// CORRECTO
var jan = new Date(2026, 0, 15); // → Enero 15
var dec = new Date(2026, 11, 15); // → Diciembre 15
// EN RIESGO — inverso: pasar valor 1-indexado estilo DatePart de vuelta al constructor
var monthFromDate = DatePart(someDate, "m"); // 5 para Mayo
var sameMonth = new Date(2026, monthFromDate, 1);
// → Junio 1 (porque Mayo=4 en tierra del constructor, 5 = Junio)
// CORRECTO
var sameMonth = new Date(2026, monthFromDate - 1, 1);La disciplina: nunca pases un valor entre el mundo DatePart/format (1-indexado) y el mundo del constructor (0-indexado) sin restar/sumar 1 explícitamente.
Strings de fecha: solo ISO 8601 — cualquier otra cosa es locale-dependiente
Construir un Date de un string que no sea ISO 8601 ("2026-05-08T14:23:11Z") da resultados engine-dependent. new Date("05/08/2026") es 8 de mayo en algunos locales, 5 de agosto en otros. Siempre usá formato ISO cuando el string cruza un límite de tenant o viene de data externa.
// EN RIESGO — parse locale-dependiente
var d = new Date("05/08/2026");
// SEGURO — ISO 8601, no ambiguo
var d = new Date("2026-05-08T00:00:00Z");
// Para date-only sin hora, agregá T00:00:00Z para mantener la porción de hora explícita
var d = new Date("2026-05-08T00:00:00Z");Decisión rápida
Usá Now() cuando:
- Necesitás el momento UTC actual para un cálculo, log timestamp, o input de DateAdd/DateDiff.
Usá Platform.Function.SystemDateToLocalDate(Now()) cuando:
- El resultado del cálculo es para un usuario (display, lógica de send-window, math de día hábil) y el timezone local del tenant importa.
Usá DateAdd(date, n, "d") (días) en lugar de (...,"m") (meses) cuando:
- El intervalo no necesita seguir el calendario exactamente.
- "Últimos 3 meses" → 90 días. Documentá la conversión.
Usá DatePart(date, "n") para minutos — nunca "m". Siempre.
Usá new Date(yyyy, mm-1, dd) (¡restá 1!) cuando:
- Construís una fecha de enteros año/mes/día.
Usá Platform.Function.FormatDate(d, "yyyy-MM-dd", loc) cuando:
- Outputeando un string de fecha a un usuario, nombre de archivo, o mensaje de log. Elegí formato ISO salvo que el locale específicamente requiera otra cosa.
Relacionado
- Basics — features soportados de SpiderMonkey 1.7
- Platform.Function —
Now(),FormatDate,SystemDateToLocalDate - Funciones de string —
FormatNumber/FormatDatepara output - MC SSJS gotchas — ver #1 (sin JS moderno — muchos métodos de Date faltantes)
- MC SQL — Funciones de fecha — hermano para la superficie SQL; trampas idénticas de UTC + month-math
Próximas páginas de referencia SSJS: Encoding · Hashing · Util / Variable · Style Guide.
Más snippets how-to para patrones comunes de producción — DE add/update/upsert, manejo de errores, paginación de callouts, etc.