Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/django/templatetags/tz.py: 33%
102 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1from datetime import datetime, tzinfo
3try:
4 import zoneinfo
5except ImportError:
6 from backports import zoneinfo
8from django.conf import settings
9from django.template import Library, Node, TemplateSyntaxError
10from django.utils import timezone
12register = Library()
15# RemovedInDjango50Warning: shim to allow catching the exception in the calling
16# scope if pytz is not installed.
17class UnknownTimezoneException(BaseException):
18 pass
21# RemovedInDjango50Warning
22def timezone_constructor(tzname):
23 if settings.USE_DEPRECATED_PYTZ:
24 import pytz
26 try:
27 return pytz.timezone(tzname)
28 except pytz.UnknownTimeZoneError:
29 raise UnknownTimezoneException
30 try:
31 return zoneinfo.ZoneInfo(tzname)
32 except zoneinfo.ZoneInfoNotFoundError:
33 raise UnknownTimezoneException
36# HACK: datetime instances cannot be assigned new attributes. Define a subclass
37# in order to define new attributes in do_timezone().
38class datetimeobject(datetime):
39 pass
42# Template filters
45@register.filter
46def localtime(value):
47 """
48 Convert a datetime to local time in the active time zone.
50 This only makes sense within a {% localtime off %} block.
51 """
52 return do_timezone(value, timezone.get_current_timezone())
55@register.filter
56def utc(value):
57 """
58 Convert a datetime to UTC.
59 """
60 return do_timezone(value, timezone.utc)
63@register.filter("timezone")
64def do_timezone(value, arg):
65 """
66 Convert a datetime to local time in a given time zone.
68 The argument must be an instance of a tzinfo subclass or a time zone name.
70 Naive datetimes are assumed to be in local time in the default time zone.
71 """
72 if not isinstance(value, datetime):
73 return ""
75 # Obtain a timezone-aware datetime
76 try:
77 if timezone.is_naive(value):
78 default_timezone = timezone.get_default_timezone()
79 value = timezone.make_aware(value, default_timezone)
80 # Filters must never raise exceptions, and pytz' exceptions inherit
81 # Exception directly, not a specific subclass. So catch everything.
82 except Exception:
83 return ""
85 # Obtain a tzinfo instance
86 if isinstance(arg, tzinfo):
87 tz = arg
88 elif isinstance(arg, str):
89 try:
90 tz = timezone_constructor(arg)
91 except UnknownTimezoneException:
92 return ""
93 else:
94 return ""
96 result = timezone.localtime(value, tz)
98 # HACK: the convert_to_local_time flag will prevent
99 # automatic conversion of the value to local time.
100 result = datetimeobject(
101 result.year,
102 result.month,
103 result.day,
104 result.hour,
105 result.minute,
106 result.second,
107 result.microsecond,
108 result.tzinfo,
109 )
110 result.convert_to_local_time = False
111 return result
114# Template tags
117class LocalTimeNode(Node):
118 """
119 Template node class used by ``localtime_tag``.
120 """
122 def __init__(self, nodelist, use_tz):
123 self.nodelist = nodelist
124 self.use_tz = use_tz
126 def render(self, context):
127 old_setting = context.use_tz
128 context.use_tz = self.use_tz
129 output = self.nodelist.render(context)
130 context.use_tz = old_setting
131 return output
134class TimezoneNode(Node):
135 """
136 Template node class used by ``timezone_tag``.
137 """
139 def __init__(self, nodelist, tz):
140 self.nodelist = nodelist
141 self.tz = tz
143 def render(self, context):
144 with timezone.override(self.tz.resolve(context)):
145 output = self.nodelist.render(context)
146 return output
149class GetCurrentTimezoneNode(Node):
150 """
151 Template node class used by ``get_current_timezone_tag``.
152 """
154 def __init__(self, variable):
155 self.variable = variable
157 def render(self, context):
158 context[self.variable] = timezone.get_current_timezone_name()
159 return ""
162@register.tag("localtime")
163def localtime_tag(parser, token):
164 """
165 Force or prevent conversion of datetime objects to local time,
166 regardless of the value of ``settings.USE_TZ``.
168 Sample usage::
170 {% localtime off %}{{ value_in_utc }}{% endlocaltime %}
171 """
172 bits = token.split_contents()
173 if len(bits) == 1:
174 use_tz = True
175 elif len(bits) > 2 or bits[1] not in ("on", "off"):
176 raise TemplateSyntaxError("%r argument should be 'on' or 'off'" % bits[0])
177 else:
178 use_tz = bits[1] == "on"
179 nodelist = parser.parse(("endlocaltime",))
180 parser.delete_first_token()
181 return LocalTimeNode(nodelist, use_tz)
184@register.tag("timezone")
185def timezone_tag(parser, token):
186 """
187 Enable a given time zone just for this block.
189 The ``timezone`` argument must be an instance of a ``tzinfo`` subclass, a
190 time zone name, or ``None``. If it is ``None``, the default time zone is
191 used within the block.
193 Sample usage::
195 {% timezone "Europe/Paris" %}
196 It is {{ now }} in Paris.
197 {% endtimezone %}
198 """
199 bits = token.split_contents()
200 if len(bits) != 2:
201 raise TemplateSyntaxError("'%s' takes one argument (timezone)" % bits[0])
202 tz = parser.compile_filter(bits[1])
203 nodelist = parser.parse(("endtimezone",))
204 parser.delete_first_token()
205 return TimezoneNode(nodelist, tz)
208@register.tag("get_current_timezone")
209def get_current_timezone_tag(parser, token):
210 """
211 Store the name of the current time zone in the context.
213 Usage::
215 {% get_current_timezone as TIME_ZONE %}
217 This will fetch the currently active time zone and put its name
218 into the ``TIME_ZONE`` context variable.
219 """
220 # token.split_contents() isn't useful here because this tag doesn't accept
221 # variable as arguments.
222 args = token.contents.split()
223 if len(args) != 3 or args[1] != "as":
224 raise TemplateSyntaxError(
225 "'get_current_timezone' requires 'as variable' (got %r)" % args
226 )
227 return GetCurrentTimezoneNode(args[2])