|
1 | | -import pytz |
2 | 1 | import datetime |
3 | 2 |
|
| 3 | +from typing import Union |
4 | 4 | from zoneinfo import ZoneInfo |
5 | 5 |
|
6 | 6 | from django.conf import settings |
|
19 | 19 | RPC_TZINFO = ZoneInfo('PST8PDT') |
20 | 20 |
|
21 | 21 |
|
22 | | -def make_aware(dt, tzinfo): |
| 22 | +def _tzinfo(tz: Union[str, datetime.tzinfo, None]): |
| 23 | + """Helper to convert a tz param into a tzinfo |
| 24 | +
|
| 25 | + Accepts Defaults to UTC. |
| 26 | + """ |
| 27 | + if tz is None: |
| 28 | + return datetime.timezone.utc |
| 29 | + elif isinstance(tz, datetime.tzinfo): |
| 30 | + return tz |
| 31 | + else: |
| 32 | + return ZoneInfo(tz) |
| 33 | + |
| 34 | + |
| 35 | +def make_aware(dt, tz): |
23 | 36 | """Assign timezone to a naive datetime |
24 | 37 |
|
25 | 38 | Helper to deal with both pytz and zoneinfo type time zones. Can go away when pytz is removed. |
26 | 39 | """ |
| 40 | + tzinfo = _tzinfo(tz) |
27 | 41 | if hasattr(tzinfo, 'localize'): |
28 | 42 | return tzinfo.localize(dt) # pytz-style |
29 | 43 | else: |
30 | 44 | return dt.replace(tzinfo=tzinfo) # zoneinfo- / datetime.timezone-style |
31 | 45 |
|
32 | 46 |
|
33 | | -def local_timezone_to_utc(d): |
34 | | - """Takes a naive datetime in the local timezone and returns a |
35 | | - naive datetime with the corresponding UTC time.""" |
36 | | - local_timezone = pytz.timezone(settings.TIME_ZONE) |
37 | | - |
38 | | - d = local_timezone.localize(d).astimezone(pytz.utc) |
39 | | - |
40 | | - return d.replace(tzinfo=None) |
41 | | - |
42 | | - |
43 | | -def datetime_from_date(date, tz=pytz.utc): |
| 47 | +def datetime_from_date(date, tz=None): |
44 | 48 | """Get datetime at midnight on a given date""" |
45 | 49 | # accept either pytz or zoneinfo tzinfos until we get rid of pytz |
46 | | - return make_aware(datetime.datetime(date.year, date.month, date.day), tz) |
| 50 | + return make_aware(datetime.datetime(date.year, date.month, date.day), _tzinfo(tz)) |
47 | 51 |
|
48 | 52 |
|
49 | | -def datetime_today(tzinfo=None): |
| 53 | +def datetime_today(tz=None): |
50 | 54 | """Get a timezone-aware datetime representing midnight today |
51 | 55 |
|
52 | 56 | For use with datetime fields representing a date. |
53 | 57 | """ |
54 | | - if tzinfo is None: |
55 | | - tzinfo = pytz.utc |
56 | | - return timezone.now().astimezone(tzinfo).replace(hour=0, minute=0, second=0, microsecond=0) |
| 58 | + return timezone.now().astimezone(_tzinfo(tz)).replace(hour=0, minute=0, second=0, microsecond=0) |
57 | 59 |
|
58 | 60 |
|
59 | | -def date_today(tzinfo=None): |
| 61 | +def date_today(tz=None): |
60 | 62 | """Get the date corresponding to the current moment |
61 | 63 |
|
62 | 64 | Note that Dates are not themselves timezone aware. |
63 | 65 | """ |
64 | | - if tzinfo is None: |
65 | | - tzinfo = pytz.utc |
66 | | - return timezone.now().astimezone(tzinfo).date() |
| 66 | + return timezone.now().astimezone(_tzinfo(tz)).date() |
67 | 67 |
|
68 | 68 |
|
69 | | -def time_now(tzinfo=None): |
| 69 | +def time_now(tz=None): |
70 | 70 | """Get the "wall clock" time corresponding to the current moment |
71 | 71 |
|
72 | 72 | The value returned by this data is a Time with no tzinfo attached. (Time |
73 | 73 | objects have only limited timezone support, even if tzinfo is filled in, |
74 | 74 | and may not behave correctly when daylight savings time shifts are relevant.) |
75 | 75 | """ |
76 | | - if tzinfo is None: |
77 | | - tzinfo = pytz.utc |
78 | | - return timezone.now().astimezone(tzinfo).time() |
| 76 | + return timezone.now().astimezone(_tzinfo(tz)).time() |
0 commit comments