Files
Starseed/frontend/shared/utils/date.ts
T
tristan 87513d130a
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m33s
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 5m19s
refactor(front) : formatDateFr mutualisé dans shared/utils/date + rendu déterministe (ERP-191)
Trois copies identiques de formatDateFr (logistique weighingTicketFormat,
transport carriers/index, CarrierQualimatTab) fusionnées en un seul helper
partagé. La nouvelle version lit la date directement dans la chaîne ISO (10
premiers caractères) au lieu de new Date(value).getDate() : un datetime porteur
d'un offset (…+02:00, …Z) ne bascule plus d'un jour selon le fuseau du
navigateur / runner CI, et reste cohérent avec l'écran d'édition (slice) et
l'export serveur (format d/m/Y).

weighingTicketFormat ré-exporte le helper (imports inchangés côté écrans).
Tests de déterminisme fuseau ajoutés dans shared/utils/date.test.ts.
2026-06-24 16:22:28 +02:00

52 lines
2.1 KiB
TypeScript

/**
* Helpers de date purs / testables (partages inter-modules).
*/
/**
* Date du jour au format ISO `YYYY-MM-DD` en heure LOCALE.
*
* On NE passe PAS par `toISOString()` (UTC) : pres de minuit, le decalage de
* fuseau (FR = UTC+1/+2) renverrait la veille ou le lendemain. On lit donc les
* composantes locales. Parametre `now` injectable pour les tests.
*/
export function todayIso(now: Date = new Date()): string {
const year = now.getFullYear()
const month = String(now.getMonth() + 1).padStart(2, '0')
const day = String(now.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}
/**
* Date-heure courante au format ISO LOCAL `YYYY-MM-DDTHH:mm:ss` (sans fuseau).
*
* C'est le format attendu par `MalioDateTime` (secondes incluses, pas d'offset
* horaire). Comme `todayIso`, on lit les composantes LOCALES (jamais
* `toISOString()`/UTC) pour ne pas décaler l'heure réelle. Paramètre `now`
* injectable pour les tests.
*/
export function nowIsoDateTime(now: Date = new Date()): string {
const hours = String(now.getHours()).padStart(2, '0')
const minutes = String(now.getMinutes()).padStart(2, '0')
const seconds = String(now.getSeconds()).padStart(2, '0')
return `${todayIso(now)}T${hours}:${minutes}:${seconds}`
}
/**
* Date courte française `JJ-MM-AAAA` à partir d'une valeur ISO (`YYYY-MM-DD` ou
* datetime `YYYY-MM-DDTHH:mm:ss±HH:mm`). Chaîne vide si absente ou non ISO.
*
* On lit les composantes DIRECTEMENT dans la chaîne (10 premiers caractères) au
* lieu de `new Date(value).getDate()` : un datetime porteur d'un offset (ex.
* `…T00:30:00+02:00`, ou `…Z`) basculerait d'un jour selon le fuseau du
* navigateur / du runner CI. Rendu ainsi déterministe et cohérent avec l'écran
* d'édition (slice de la chaîne brute) et l'export serveur (`format('d/m/Y')`).
*/
export function formatDateFr(value: string | null | undefined): string {
const match = value ? /^(\d{4})-(\d{2})-(\d{2})/.exec(value) : null
if (!match) {
return ''
}
const [, year, month, day] = match
return `${day}-${month}-${year}`
}