From e1bdd1e45ea5045a65f0c4956bec2b43e977e774 Mon Sep 17 00:00:00 2001 From: Xavier Leune Date: Tue, 1 Sep 2026 14:51:49 +0200 Subject: [PATCH] =?UTF-8?q?Correction=20du=20d=C3=A9calage=20horaire=20des?= =?UTF-8?q?=20horaires=20de=20planning=20c=C3=B4t=C3=A9=20public?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le filtre date de Twig ne se contente pas de formater : il convertit la date vers la timezone par défaut de Twig, c'est-à-dire celle de PHP, en ignorant celle portée par l'objet DateTime. Les horaires étant stockés en timestamp, la page programme (et les autres affichages) montraient donc de l'UTC en production, où PHP tourne en UTC, alors que le conteneur de dev est en Europe/Paris. Planning::TIMEZONE est désormais exposée à Twig via le global planning_timezone, et passée explicitement à chaque affichage d'un horaire de planning : page programme, widget talk, espace conférencier et back-office (qui recevait jusqu'ici la constante via une variable de rendu dédiée, maintenant redondante). L'export CSV pour joind.in formatait lui aussi les horaires dans la timezone du serveur : il les convertit désormais dans celle de l'événement. --- config/packages/twig.yaml | 1 + .../Controller/Admin/Event/Session/IndexAction.php | 1 - sources/AppBundle/Event/Talk/ExportGenerator.php | 12 ++++++++++-- templates/blog/program.html.twig | 4 ++-- templates/blog/talk.html.twig | 4 ++-- templates/event/session/index.html.twig | 4 ++-- templates/event/speaker/page.html.twig | 2 +- 7 files changed, 18 insertions(+), 10 deletions(-) diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index a5223d184..6720b9be7 100644 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -4,5 +4,6 @@ twig: globals: photo_storage: '@AppBundle\CFP\PhotoStorage' global_menu_event_label: '%env(AFUP_GLOBAL_MENU_EVENT_LABEL)%' + planning_timezone: !php/const AppBundle\Event\Model\Planning::TIMEZONE form_themes: ['form_theme.html.twig'] default_path: "%kernel.project_dir%/templates" diff --git a/sources/AppBundle/Controller/Admin/Event/Session/IndexAction.php b/sources/AppBundle/Controller/Admin/Event/Session/IndexAction.php index fa4835d9d..4960342b6 100644 --- a/sources/AppBundle/Controller/Admin/Event/Session/IndexAction.php +++ b/sources/AppBundle/Controller/Admin/Event/Session/IndexAction.php @@ -38,7 +38,6 @@ public function __invoke(Request $request, AdminEventSelection $eventSelection): 'events' => $this->calendarEvents($sessions), 'resources' => $this->calendarResources($event), ], - 'timezone' => Planning::TIMEZONE, ]); } diff --git a/sources/AppBundle/Event/Talk/ExportGenerator.php b/sources/AppBundle/Event/Talk/ExportGenerator.php index 472d3ebf2..067d1a524 100644 --- a/sources/AppBundle/Event/Talk/ExportGenerator.php +++ b/sources/AppBundle/Event/Talk/ExportGenerator.php @@ -5,6 +5,7 @@ namespace AppBundle\Event\Talk; use AppBundle\Event\Model\Event; +use AppBundle\Event\Model\Planning; use AppBundle\Event\Model\Repository\TalkRepository; use AppBundle\Event\Model\Speaker; use AppBundle\Event\Model\Talk; @@ -56,6 +57,8 @@ public function exportJoindIn(Event $event, \SplFileObject $toFile): void $toFile->fputcsv(['Title','Description','Speaker','Date','Time','Type'], escape: '\\'); + $timezone = new \DateTimeZone(Planning::TIMEZONE); + foreach ($talkAggregates as $talkAggregate) { // Gestion de la description @@ -72,6 +75,11 @@ public function exportJoindIn(Event $event, \SplFileObject $toFile): void } $speakers = implode(',', $speakers); + // Gestion des horaires : stockés en timestamp, ils sont exportés dans la + // timezone de l'événement et non dans celle du serveur. + $start = $talkAggregate->planning?->getStart(); + $start = $start === null ? null : \DateTimeImmutable::createFromInterface($start)->setTimezone($timezone); + // Gestion du type de conférence if ($talkAggregate->planning?->getIsKeynote()) { $type = 'Keynote'; @@ -85,8 +93,8 @@ public function exportJoindIn(Event $event, \SplFileObject $toFile): void $talkAggregate->talk->getTitle(), $abstract, $speakers, - $talkAggregate->planning?->getStart()?->format('Y-m-d'), - $talkAggregate->planning?->getStart()?->format('H:i'), + $start?->format('Y-m-d'), + $start?->format('H:i'), $type, ], escape: '\\'); } diff --git a/templates/blog/program.html.twig b/templates/blog/program.html.twig index a79c918d3..5d60461a1 100644 --- a/templates/blog/program.html.twig +++ b/templates/blog/program.html.twig @@ -31,9 +31,9 @@

{{ talk.talk.title|raw }}

{% if talk.planning is not null and event.isPlanningDisplayable %} {{ talk.room.name }} - {{ talk.planning.start|date('d/m/Y') }} + {{ talk.planning.start|date('d/m/Y', planning_timezone) }} - {{ talk.planning.start|date('H:i') }}-{{ talk.planning.end|date('H:i') }} + {{ talk.planning.start|date('H:i', planning_timezone) }}-{{ talk.planning.end|date('H:i', planning_timezone) }} - Niveau : {{ talk.talk.skillTranslationKey|trans }} {% if talk.talk.languageCode %}- {{ talk.talk.languageLabel }}{% endif %} diff --git a/templates/blog/talk.html.twig b/templates/blog/talk.html.twig index 9f467e4fd..31ec3115a 100644 --- a/templates/blog/talk.html.twig +++ b/templates/blog/talk.html.twig @@ -20,8 +20,8 @@ {% if talks_info.event.isPlanningDisplayable %} {{ talks_info.room.name }}
- {{ talks_info.planning.start|date('d/m/Y') }}
- {{ talks_info.planning.start|date('H:i') }}-{{ talks_info.planning.end|date('H:i') }} + {{ talks_info.planning.start|date('d/m/Y', planning_timezone) }}
+ {{ talks_info.planning.start|date('H:i', planning_timezone) }}-{{ talks_info.planning.end|date('H:i', planning_timezone) }} {% endif %} diff --git a/templates/event/session/index.html.twig b/templates/event/session/index.html.twig index 52f1b2871..ae89f3db1 100644 --- a/templates/event/session/index.html.twig +++ b/templates/event/session/index.html.twig @@ -116,8 +116,8 @@
{% if session.planning %} - {{ session.planning.start|date("d/m/Y", timezone) }} / - {{ session.planning.start|date("H:i", timezone) }} - {{ session.planning.end|date("H:i", timezone) }} / {{ session.room ? session.room.name }} + {{ session.planning.start|date("d/m/Y", planning_timezone) }} / + {{ session.planning.start|date("H:i", planning_timezone) }} - {{ session.planning.end|date("H:i", planning_timezone) }} / {{ session.room ? session.room.name }} {% else %} non planifié {% endif %} diff --git a/templates/event/speaker/page.html.twig b/templates/event/speaker/page.html.twig index 71e4546a2..261bad13d 100644 --- a/templates/event/speaker/page.html.twig +++ b/templates/event/speaker/page.html.twig @@ -87,7 +87,7 @@ {% if talk_info.planning %} {% if talk_info.room %}({{ talk_info.room.name }}){% endif %} - ({{ talk_info.planning.start|format_datetime('full', 'short') }}) + ({{ talk_info.planning.start|format_datetime('full', 'short', timezone=planning_timezone) }}) {% else %} (salle et dates de passage à venir) {% endif %}