From 11df4398e178dc58b2511c06dbd28219588cc276 Mon Sep 17 00:00:00 2001
From: Phin Wolkwitz
Date: Wed, 17 Dec 2025 16:18:59 +0100
Subject: [PATCH] Fix presale date display in calendar (Z#23216645) (#5710)
Fix presale date display in calendar and introduce a template tag
---
src/pretix/base/templatetags/html_time.py | 65 +++++++++++++++++++
.../event/fragment_event_info.html | 37 +++++------
.../templates/pretixpresale/event/order.html | 6 +-
.../pretixpresale/fragment_calendar.html | 10 +--
.../pretixpresale/fragment_day_calendar.html | 8 ++-
.../fragment_event_list_status.html | 6 +-
.../pretixpresale/fragment_week_calendar.html | 8 ++-
src/pretix/presale/views/widget.py | 5 +-
8 files changed, 106 insertions(+), 39 deletions(-)
create mode 100644 src/pretix/base/templatetags/html_time.py
diff --git a/src/pretix/base/templatetags/html_time.py b/src/pretix/base/templatetags/html_time.py
new file mode 100644
index 0000000000..55b4fc224d
--- /dev/null
+++ b/src/pretix/base/templatetags/html_time.py
@@ -0,0 +1,65 @@
+#
+# This file is part of pretix (Community Edition).
+#
+# Copyright (C) 2014-2020 Raphael Michel and contributors
+# Copyright (C) 2020-today pretix GmbH and contributors
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
+# Public License as published by the Free Software Foundation in version 3 of the License.
+#
+# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
+# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
+# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
+# this file, see .
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
+# .
+#
+from datetime import datetime
+
+from django import template
+from django.utils.html import format_html
+from django.utils.timezone import get_current_timezone
+
+from pretix.base.i18n import LazyExpiresDate
+from pretix.helpers.templatetags.date_fast import date_fast
+
+register = template.Library()
+
+
+@register.simple_tag
+def html_time(value: datetime, dt_format: str = "SHORT_DATE_FORMAT", **kwargs):
+ """
+ Building a html string,
+ where the html-datetime as well as the human-readable datetime can be set
+ to a value from django's FORMAT_SETTINGS or "format_expires".
+
+ If attr_fmt isn’t provided, it will be set to isoformat.
+
+ Usage example:
+ {% html_time event_start "SHORT_DATETIME_FORMAT" %}
+ or
+ {% html_time event_start "TIME_FORMAT" attr_fmt="H:i" %}
+ """
+ if value in (None, ''):
+ return ''
+ value = value.astimezone(get_current_timezone())
+ attr_fmt = kwargs["attr_fmt"] if kwargs else None
+
+ try:
+ if not attr_fmt:
+ date_html = value.isoformat()
+ else:
+ date_html = date_fast(value, attr_fmt)
+
+ if dt_format == "format_expires":
+ date_human = LazyExpiresDate(value)
+ else:
+ date_human = date_fast(value, dt_format)
+ return format_html("", date_html, date_human)
+ except AttributeError:
+ return ''
diff --git a/src/pretix/presale/templates/pretixpresale/event/fragment_event_info.html b/src/pretix/presale/templates/pretixpresale/event/fragment_event_info.html
index c755f23ace..6b6fbc0929 100644
--- a/src/pretix/presale/templates/pretixpresale/event/fragment_event_info.html
+++ b/src/pretix/presale/templates/pretixpresale/event/fragment_event_info.html
@@ -1,3 +1,4 @@
+{% load html_time %}
{% load i18n %}
{% load icon %}
{% load eventurl %}
@@ -21,20 +22,18 @@
{% if event.settings.show_times %}
- {% with time_human=ev.date_from|date:"TIME_FORMAT" time_24=ev.date_from|time:"H:i" %}
- {% blocktrans trimmed with time='"|safe %}
- Begin: {{ time }}
- {% endblocktrans %}
- {% endwith %}
+ {% html_time ev.date_from "TIME_FORMAT" attr_fmt="H:i" as time%}
+ {% blocktrans with time=time %}
+ Begin: {{ time }}
+ {% endblocktrans %}
{% if event.settings.show_date_to and ev.date_to %}
- {% with time_human=ev.date_to|date:"TIME_FORMAT" time_24=ev.date_to|time:"H:i" %}
- {% blocktrans trimmed with time='"|safe %}
- End: {{ time }}
- {% endblocktrans %}
- {% endwith %}
+ {% html_time ev.date_to "TIME_FORMAT" attr_fmt="H:i" as time%}
+ {% blocktrans with time=time %}
+ End: {{ time }}
+ {% endblocktrans %}
{% endif %}
{% endif %}
@@ -42,19 +41,17 @@
{% if ev.date_admission|date:"SHORT_DATE_FORMAT" == ev.date_from|date:"SHORT_DATE_FORMAT" %}
- {% with time_human=ev.date_admission|date:"TIME_FORMAT" time_24=ev.date_admission|time:"H:i" %}
- {% blocktrans trimmed with time='"|safe %}
- Admission: {{ time }}
- {% endblocktrans %}
- {% endwith %}
+ {% html_time ev.date_admission "TIME_FORMAT" attr_fmt="H:i" as time%}
+ {% blocktrans trimmed with time=time %}
+ Admission: {{ time }}
+ {% endblocktrans %}
{% else %}
- {% with datetime_human=ev.date_admission|date:"SHORT_DATETIME_FORMAT" datetime_iso=ev.date_admission|time:"Y-m-d H:i" %}
- {% blocktrans trimmed with datetime='"|safe %}
- Admission: {{ datetime }}
- {% endblocktrans %}
- {% endwith %}
+ {% html_time ev.date_admission "SHORT_DATETIME_FORMAT" attr_fmt="Y-m-d H:i" as datetime%}
+ {% blocktrans trimmed with datetime=datetime %}
+ Admission: {{ datetime }}
+ {% endblocktrans %}
{% endif %}
{% endif %}
diff --git a/src/pretix/presale/templates/pretixpresale/event/order.html b/src/pretix/presale/templates/pretixpresale/event/order.html
index 5583b279fc..89e20f6007 100644
--- a/src/pretix/presale/templates/pretixpresale/event/order.html
+++ b/src/pretix/presale/templates/pretixpresale/event/order.html
@@ -1,4 +1,5 @@
{% extends "pretixpresale/event/base.html" %}
+{% load html_time %}
{% load i18n %}
{% load bootstrap3 %}
{% load eventsignal %}
@@ -92,11 +93,10 @@
A payment of {{ total }} is still pending for this order.
{% endblocktrans %}
- {% with date_human=order|format_expires|safe date_iso=order.expires|date:"c" %}
- {% blocktrans trimmed with date='"|safe %}
+ {% html_time order.expires "format_expires" as date %}
+ {% blocktrans trimmed with date=date %}
Please complete your payment before {{ date }}
{% endblocktrans %}
- {% endwith %}