Actions de date
La famille d'actions date effectue le travail sur les dates sensible au fuseau horaire et à la locale à l'intérieur d'une automatisation : rendre un instant, en relire un depuis une chaîne, le décaler, mesurer entre deux instants et se caler sur une borne de calendrier. Huit opérateurs, pas un de plus — les absences sont délibérées et sont listées en fin de page.
- name: dueLabel
type: date
operator: format
props:
input: '{{trigger.data.dueAt}}'
pattern: "EEEE d MMMM yyyy 'à' HH:mm"
timezone: Europe/Paris
locale: fr-FRLes opérateurs
| Opérateur | Props requises | Props optionnelles | Sortie |
|---|---|---|---|
format |
input, pattern |
timezone, locale |
{ formatted } |
parse |
input, pattern |
timezone |
{ instant, valid } |
add |
input + ≥1 composant |
timezone |
{ instant } |
subtract |
input + ≥1 composant |
timezone |
{ instant } |
diff |
from, to, unit |
timezone |
{ value } |
startOf |
input, unit |
timezone |
{ instant } |
endOf |
input, unit |
timezone |
{ instant } |
now |
(aucune) | pattern, timezone, locale |
{ instant }, plus formatted avec un pattern |
instant est toujours une chaîne ISO 8601, jamais un Date : une sortie d'étape est persistée en JSON dans l'historique d'exécution, relue par les templates et renvoyée dans les corps de webhook, et un Date ne survit à aucun de ces sauts avec son type intact.
timezone est un identifiant IANA (Europe/Paris), avec UTC par défaut. Un instant ne porte aucun fuseau propre — timezone est ce dans quoi l'instant est lu. Un décalage fixe (+02:00) est accepté mais ne peut pas exprimer l'heure d'été : préférez un fuseau nommé partout où elle s'applique. locale est une étiquette BCP 47 (fr-FR, en-US par défaut) et n'affecte que les jetons de nom de mois et de jour ; un pattern purement numérique l'ignore.
Le jeu de jetons est fermé
pattern s'écrit en jetons Unicode LDML, et le vocabulaire est fermé :
| Jeton | Signification | Analysable |
|---|---|---|
yyyy |
Année civile, 4 chiffres (2026) | oui |
MM |
Mois, 2 chiffres (01–12) | oui |
dd |
Jour du mois, 2 chiffres (01–31) | oui |
HH |
Heure, 2 chiffres, format 24 h (00–23) | oui |
mm |
Minute, 2 chiffres (00–59) | oui |
ss |
Seconde, 2 chiffres (00–59) | oui |
MMMM |
Nom du mois, complet, localisé (mars) | non |
MMM |
Nom du mois, court, localisé (mars) | non |
EEEE |
Nom du jour, complet, localisé (samedi) | non |
EEE |
Nom du jour, court, localisé (sam.) | non |
YYYY |
Alias hérité de yyyy |
oui |
DD |
Alias hérité de dd |
oui |
Un jeton non reconnu est une erreur, pas un passe-plat. Chaque lettre ASCII hors littéral entre guillemets doit appartenir à un jeton du tableau ci-dessus — c'est la règle de LDML elle-même, où les lettres sont réservées. Mettez les lettres littérales entre apostrophes : "yyyy-MM-dd'T'HH:mm:ss". Les non-lettres (- / : espace) sont des littéraux et passent tels quels. Fermer le jeu est ce qui garde cette surface finie et testable : dès qu'un vocabulaire complet de quarante jetons est sous-entendu, les quarante sont dus.
Les quatre jetons de nom sont marqués non analysables. parse ne prend donc pas de locale, et un pattern contenant MMMM ou EEEE est rejeté du côté analyse — mars est ambigu selon les locales et les styles d'abréviation, et l'accepter relèverait de la devinette plutôt que de l'analyse.
parse rend la validité sous forme de donnée
- name: readDueDate
type: date
operator: parse
props:
input: '{{trigger.data.dueDate}}'
pattern: dd/MM/yyyy
timezone: Europe/ParisLa sortie est { instant, valid }. Une chaîne qui ne correspond pas au pattern fait réussir l'étape avec valid: false et un instant null, plutôt que de la faire échouer. C'est délibéré, et deux comportements en dépendent :
- Les tentatives. Une étape en échec est retentée selon sa configuration
retry. Retenter un verdict déterministe consomme le budget et retarde l'exécution pour un résultat qui ne peut pas changer. - Le flux de contrôle. Une étape en échec arrête la branche sauf si
continueOnErrorest défini, si bien qu'unfilterou unpathen aval censé router les lignes invalides ne s'exécuterait jamais. Renvoyer une donnée laisse la décision là où un auteur peut agir dessus.
Un pattern malformé est le cas inverse — une erreur d'auteur, pas une donnée — et fait bien échouer l'étape.
- name: routeInvalid
type: filter
operator: continue
props:
condition:
conditions:
- field: '{{readDueDate.valid}}'
operator: equals
value: true
onFalse: skipArithmétique : unités de calendrier et temps écoulé
add et subtract prennent au moins un composant de durée. Les quantités sont au pluriel (days: 7) alors que les noms d'unités ailleurs sont au singulier — quantités contre noms, le même partage que celui de Temporal et de java.time. N'en déclarer aucun est une erreur de configuration.
| Composant | Résolu comme |
|---|---|
years |
Calendrier — sensible à l'heure d'été, heure murale préservée |
months |
Calendrier — 31 janvier + 1 mois donne le 28 février |
weeks |
Calendrier — sensible à l'heure d'été, heure murale préservée |
days |
Calendrier — un jour à cheval sur un changement d'heure fait 23 ou 25 h |
hours |
Écoulé — une heure fait toujours 60 minutes |
minutes |
Écoulé — insensible à l'heure d'été |
seconds |
Écoulé — insensible à l'heure d'été |
Le jour et au-dessus relèvent du calendrier, l'heure et en dessous sont fixes. Ajouter { days: 1 } à midi à Europe/Paris au passage à l'heure d'été donne midi le lendemain — 23 heures réelles plus tard. Ajouter { hours: 24 } donne 13 h — 24 heures réelles plus tard. Les deux sont des réponses correctes à des questions différentes, et ce partage est ce qui garde l'accord entre add: { hours: 3 } et un diff en hour qui le suit. diff trace la même ligne : hour et en dessous sont de longueur fixe et ignorent totalement le fuseau.
Les grandes unités s'appliquent avant les petites, si bien que le rabotage de fin de mois a lieu en premier : 31 janvier + { months: 1, hours: 6 } est ramené au 28 février puis reçoit six heures.
- name: reminderAt
type: date
operator: subtract
props:
input: '{{trigger.data.dueAt}}'
days: 2
hours: 3
timezone: Europe/Parisdiff — signé et tronqué vers zéro
- name: daysLate
type: date
operator: diff
props:
from: '{{trigger.data.dueAt}}'
to: '{{now.instant}}'
unit: day
timezone: Europe/Parisunit est au singulier : year, month, week, day, hour, minute, second ou millisecond. Le résultat est signé — négatif quand to précède from — et tronqué vers zéro, si bien qu'un écart de 47 heures vaut un day, pas deux. Les unités de calendrier sont comptées contre le fuseau, celles de temps écoulé non.
Comme diff répond déjà avec un signe, il n'existe pas d'opérateurs isBefore / isAfter / isBetween ; comparez plutôt le résultat dans une condition de filter ou de path.
startOf / endOf — bornes de calendrier
- name: monthStart
type: date
operator: startOf
props:
input: '{{trigger.data.occurredAt}}'
unit: month
timezone: Europe/Parisunit vaut year, month, week, day, hour, minute ou second — le même vocabulaire singulier que diff, moins millisecond, sur lequel aucune borne ne se cale. La borne est calculée dans timezone : le début d'un jour à Europe/Paris est donc 22 h ou 23 h UTC la veille au soir, selon la saison.
now
- name: stamp
type: date
operator: now
props:
pattern: yyyy-MM-dd
timezone: Europe/ParisRenvoie { instant } — un instant UTC — et ajoute formatted lorsqu'un pattern est fourni. C'est le seul opérateur sans prop requise.
Ce qui est délibérément absent
Les huit opérateurs ont été choisis contre un domaine de capacités plutôt que contre la surface d'API d'une bibliothèque de dates, si bien que plusieurs noms familiers manquent volontairement :
isBefore/isAfter/isBetween— relèvent d'une condition defilterou depath;diffrenvoie déjà une réponse signée.toTimezone— un instant ne porte aucun fuseau, donc ce nom enseigne un modèle faux. Letimezonedeformatcouvre le besoin.dayOfWeek/isWeekday/isWeekend—formatavecEEEE, plus un filtre. Trois opérateurs pour un seul jeton, c'est exactement la prolifération que cette famille existe pour éviter.timestamp/fromTimestamp— les jetons d'epoch sont une question de jeu de jetons, pas d'opérateur.- L'arithmétique de jours ouvrés et de jours fériés — exige un calendrier que la plateforme n'a pas, et une réponse fausse y est pire que pas de réponse.
Appeler les opérateurs de date depuis du code
Chaque opérateur est joignable depuis une action code via context.actions.date.<operator>(props). Ce chemin ne décode pas les props contre le schéma : le gestionnaire réapplique donc lui-même les garde-fous — un fuseau invalide ou un jeton non reconnu y échoue exactement comme il le ferait au démarrage.
Pages liées
- Vue d'ensemble des actions — le modèle d'action et toutes les familles.
- Données et état —
filter/continue, où un verdict deparseest routé. - Contrôle de flux —
path/branchpour un routage piloté par les dates. - Déclencheurs — le déclencheur
cron, qui partage ce vocabulaire de fuseaux. - Actions de code — le chemin d'appel
context.actions.date.
Dernière mise à jour 28 août 2026
Cette documentation a été rédigée avec de l'IA : des erreurs ou du contenu obsolète sont donc possibles. Sovrium est en bêta. Les contributions et corrections sont les bienvenues.