J’ai creusé ce bug, il y a en fait trois symptômes distincts qui partagent une seule et même cause.
La cause
Le front utilise dayjs pour tous ses calculs de dates. Une box du tableau de bord (EDF Tempo) chargeait le plugin timezone de dayjs pour lire l’heure de Paris.
Le problème : dayjs.extend() modifie globalement dayjs, pour toute l’application. Et la bibliothèque du calendrier (react-big-calendar) contient ce test :
// if the timezone plugin is loaded, then use the timezone aware version
const dayjs = dayjsLib.tz ? dayjsLib.tz : dayjsLib;
Dès que le plugin est présent, le calendrier bascule tous ses calculs sur dayjs.tz, qui se comporte différemment :
il interprète certaines dates comme de l’UTC → la grille horaire glisse de 2h
add(1, ‹ jour ›) ajoute 24h absolues, alors que le jour du passage à l’heure d’hiver en dure 25 → on retombe à 23h le même jour, d’où la date affichée deux fois
startOf(‹ mois ›) se décale d’une heure, ce qui fausse la comparaison des mois → le grisage s’inverse
Point important : cette box était importée statiquement avec toutes les autres, donc le plugin se chargeait même si vous n’utilisiez jamais EDF Tempo.
Le correctif
Plutôt que de rustiner le calendrier, j’ai supprimé la cause : la box EDF Tempo utilise maintenant Intl.DateTimeFormat (natif, sans effet de bord) pour lire l’heure de Paris. Le comportement métier est identique — les heures pleines/creuses restent définies en heure française quel que soit votre fuseau.
Il reste un correctif dans le calendrier, pour un bug indépendant de celui-ci : le jour du changement d’heure affichait 26 lignes horaires en octobre et 22 en mars au lieu de 24, et les événements y étaient mal positionnés (un rendez-vous de 14h s’affichait à 13h26).