Retour d'expérience d'une problématique de Date & Time

YouStock

Missions
1. Déménagement
1.2 Emballage
1.3 Collecte
1.3.1 Chargement
1.3.2 Déchargement
2. Stockage en entrepôt dans des box connectés
2.1 Chargement
2.2 Déchargement
3. Relivraison
2.1 Chargement
2.2 Déchargement
Workflow (rapide)
1. Le client fait une demande en ligne (déménagement ou stockage)
2. Estimation avec devis en ligne
3. Le commercial rappelle presque systématiquement pour l'organisation (pôle Sales)
4. Génération des dates liées à la prestation
5. X instant avant (2 jours avant, 24h avant) : envoi de notification (EMail, SMS)
6. Jour J de la prestation : la mission débute
Logistique des entrepôts de stockage
- Autorisation des clients à venir retirer / voir leurs affaires durant certaines heures
- Chaque box est utilisé durant une période
- Synchronisation des plannings des prestataires de livraison / de déménagement selon les localisations des missions
La lettre de voiture
- Réglementée par le Code du commerce: par pays et par chauffeur à chaque action d'un chauffeur lors d'une mission, la lettre de voiture :
- A une durée de validité encadrée
- Est synchronisée entre 2 chauffeurs / pays / instant
- Générée par une application, sans tenir compte des détails d'instant
Lieu géographique
- En France
- En Angleterre
- En Belgique
- Monaco
- Les DOM-TOM
Dans les tuyaux pour viser une énième levée de fond :
- Canada
- Amérique
...Problème de date & time
- L'application ne tient pas compte de détails du fuseau horaire : la fameuse "Time Zone"
-
Beaucoup de dates manuellement gérées par les commerciaux
-
Qui et quoi est concerné ?
- Déménagement
- chargement
- déchargement
- Relivraison
- chargement
- déchargement
- Trajet :
- lettre de voiture (début / fin)
- Synchronisation sur l'application Mobile
- Date de chaque "action"
- Des photos des objets stockés et datés pour rassurer
- SMS de confirmation avec une date & time
- Emails de suivis de chaque Instant avec du date & time
Champion du tout "a la mano"
- Rattrapage des durées erronées par les commerciaux, parfois lors d'une relivraison qui est faite dans le futur:
- Rattrapage des imprécisions sur les lettres de voiture qui doivent être précises, notamment à l'international lors de changement de prestataire, lorsqu'elles sont générées dans le futur ET dans un autre pays
- Feature pour indiquer les décalages horaire de toute l'année pour "aider" à rectifier les plannings des transporteurs :
- Disponibilité des prestataires aux mêmes instants...à l'heure près
- Un dev' custom mal ou pas du tout utilisé, pas pratique
Le parallèle avec "UTC" & "Time Zone"
UTC
-
UTC (Temps Universel Coordonné / Coordinated Universal Time) est le temps de référence utilisé à l’échelle mondiale pour la coordination des horloges et des SI / des machines connectés
- Norme scientifique basée sur des horloges atomiques pour la stabilité et la précision
- UTC ne dépend d’aucun fuseau horaire géographique : il reste constant, non basé sur les décalages horaire
Usage de l'UTC
- Utilisé pour du log d'événements passés, synchroniser des TIC et éviter les erreurs liées aux fuseaux horaires (Time Zone).
Exemple de domaine d'utilisation :
L’aviation (plans de vol en UTC)
Les satellites et les télécoms
Les serveurs
Les blockchains
- Il est au cœur de 2 standards :
- la RFC 3339
- la norme ISO 8601
RFC-3339
- Basé sur l'ISO 8601 MAIS strict => pour les machines
- Limite volontairement le format pour assurer une meilleure interopérabilité
- N’utilise pas les noms de zones horaires (ex. Europe/Paris est exclu)
- Un offset explicite est nécessaire :
- (+00:00, -05:00, etc.)
- "Z" pour indiquer "UTC au point 0" (“Zulu time”, code militaire pour UTC)
- Adapté aux machines (ex. : logs, APIs, bases de données).
- "2025-06-27T13:45:00Z"
- Exemple sans "T" de séparation (valide mais moins courant) :
-
"2025-06-27 14:00:00+02:00"
-

What ? Paris...c'est UTC+1 ou +2 ?!
- Pendant la Seconde Guerre mondiale, tous les territoires occupés, dont la Belgique, adoptent l'heure allemande :
- UTC+1 en hiver
- UTC+2 en été
- La Belgique décide toutefois de conserver l'heure allemande (UTC+1), alors que l'heure d'été avait été supprimé dans plusieurs pays (en 1946)
- Cette décision correspond à une « avancée » de l'heure légale de 60 minutes par rapport à l'UTC.
- Depuis, ce décalage est maintenu pour l'heure d'hiver.
...et encore aujourd'hui
- Turquie (2015) : Annule le retour à l'heure standard une semaine avant les élections pour rester en heure d’été.
- Liban (2023) : Décale le passage à l’heure d’été de mars à avril, décision annoncée seulement 48 h avant.
- Russie (2011) : Supprime complètement l’heure d’hiver et reste en heure d’été toute l’année.
- Brésil (ex. 2019) : Met fin au passage à l’heure d’été, décision prise quelques semaines avant l’échéance.
- etc
- etc
- etc

Double TimeZone possible au même moment de l'année
Inconvénient de la RFC-3339
Ne prend pas en compte ces règles (https://www.iana.org/time-zones), on parle de :
- DST : Daylight Saving Rule
- MST : Mountain Standard Time
La RFC indique clairement ce choix :
- Because the daylight saving rules for local time zones are so
convoluted and can change based on local law at unpredictable times, true interoperability is best achieved by using Coordinated Universal Time (UTC). This specification does not cater to local time zone rules.
Anticiper le futur
Besoins de YouStock :
- anticiper les changements d'heure non-prévus pour les dates dans le futur (DST)
- chaque date, aux instants dans le futur doivent être (re)calculables par rapport à ces changements d'heures
- on tient compte de la zone géographique
- on peut calculer entre 2 lieux de 2 missions la "durée"
- pour les dates "non futur" (plus orienté machine) : on aura de l'UTC
We need TZ, we need ISO-8061
- Zone horaire nommée :
- Ex. : 2025-06-27T14:00:00[Europe/Paris]
- Syntaxe en Java , mais pas standardisé officiellement (voir la JSR 310)
- Couvre une large variété de formats : date seule, heure seule, horodatage complet
- Ex. : 2025-06-27T14:00:00[Europe/Paris]
- Permet d'avoir une communication à l’échelle mondiale sans perdre l'intention réel de l'utilisateur
- Compatible avec la RFC-3339 et le format UTC :
- Ex. : → 2025-06-27T14:00:00+02:00
Comparaison
| Caractéristique | ISO 8601 | RFC 3339 |
|---|---|---|
| Support du nom de Time Zone | Oui, via extensions (ex. `[Europe/Paris]`) | ❌ Non (seulement offset numérique) |
| Utilisation du décalage UTC | ✅ Oui | ✅ Oui (obligatoire) |
| Prise en compte du DST | Possible via la Time Zone nommée | ❌ Non |
| Objectif | Communication mondiale | Traitement machine / interopérabilité |
Composant brick/date-time
https://github.com/brick/date-time
Benjamain Morel
composer require brick/date-time
Composants "Brick" (money, math), c'est lui !
Brick/Date-Time : ISO-8601 étendu JSR-310
Les classes intéressantes
- Duration: a duration measured in seconds and nanoseconds
- Instant: a point in time, with a nanosecond precision
- LocalDate: an isolated date such as 2014-08-31
- LocalDateTime: a date-time without a time-zone, such as 2014-08-31T10:15:30
- TimeZoneOffset: an offset-based time-zone, such as +01:00
- TimeZoneRegion: a region-based time-zone, such as Europe/London
- ZonedDateTime: a date-time with a time-zone OFFSET, such as 2014-08-31T10:15:30+01:00. This class is conceptually equivalent to the native DateTime class...
- RegionZonedDateTime: a date-time OFFSET + time-zone region, such as 2014-08-31T10:15:30+01:00[Europe/Paris]. We keep the actuel UTC plus the information of the Region.
La DX
- Chaque méthode :
- retourne une nouvelle instance (=> new self(XX) ) ce qui permet d’enchaîner les méthodes facilement et c'est immutable
- se situe dans un contexte "static" de la classe, isolé
- Le Domain date & time sont "explicites" et pour les besoins les plus courants, on aura par ex.
- $t = RegionZonedDateTime::of(TimeZone::parse('Europe/Paris')),
-
$newTime = $t
->withSeconds()
->withTimezoneSameLocale()
->plus(Duration::of())
->minus(Duration::of())
Exemple (en démo)
Conclusion
...et YouStock ?
✅ Les lettres de voitures ont leurs dates synchronisées sur les fuseaux horaire (Time Zone), elles sont à jour automatiquement
✅ Les dates qui remontent depuis l'API sur l'application Mobile sont corrects
✅ Les commerciaux ne font plus de "retouche", tout est automatisé, ils se concentrent sur les "lead"
✅La gestion des plannings n'a plus d'erreurs : une Mission démarre et se termine au bon moment
✅Suppression du code legacy "planning manuel"...qui ne servait pas
Toutes les dates dans le futur sont ISO-8601 JSR 310
...et YouStock ?
✅ UTCDateTime::now() remplace les "new \DateTimeImmutable()" étaient présents
Toutes les dates dans le passé sont ISO-8601 avec la TimeZone...UTC !
Merci pour votre :oreille:, des questions ?
La présentation, ce "mot" et celui "là" sont déjà dans le passé...
Date Time
By Florian CELLIER
Date Time
- 21