I am currently working on a backend for a calendar system that returns naive Python dates. How the external interface works, the user creates various calendar events, and the interface returns a naive version of the created event (for example, if the user selects October 5, 2020 from 15:00 to 16:00, the datetime.datetime interface is returned (2020, 10, 5, 15 , 0, 0) as the beginning and datetime.datetime (2011, 10, 5, 16, 0, 0) as the end.
What I need to do is take a naive datetime and convert it to UTC for storage in the database. Each user of the system has already indicated their preference for the time zone, so the naive datetime is considered the same time zone as their time preference. Obviously, the data should be stored relative to UTC, so if users change their time zone, existing events will be displayed at the correct time that they scheduled.
The external interface is out of my control, so I can not change the data that I receive. The database design is also out of my control, so I cannot change what data is stored and how.
Here's an approximate approach I've taken so far:
import pytz def convert_to_UTC(naive_datetime, user_tz_preference): user_datetime = naive_datetime.replace(tzinfo=user_tz_preference) utc_datetime = user_datetime.astimezone(pytz.utc)
The problem I encountered is related to summer time savings:
>>> from datetime import datetime >>> import pytz >>> user_tz_preference = pytz.timezone('US/Pacific') >>> naive_datetime = datetime(2011, 10, 26, 12, 0, 0) >>> user_datetime = naive_datetime.replace(tzinfo=user_tz_preference) >>> user_datetime datetime.datetime(2011, 10, 26, 12, 0, tzinfo=<DstTzInfo 'US/Pacific' PST-1 day, 16:00:00 STD>) >>> received_utc = user_datetime.astimezone(pytz.utc) >>> received_utc datetime.datetime(2011, 10, 26, 20, 0, tzinfo=<UTC>) >>> expected_utc = datetime(2011, 10, 26, 19, 0, tzinfo=pytz.utc) >>> expected_utc == received_utc False
Note that using βreplaceβ sets the time zone for PST instead of PDT, regardless of the date, which gives it a UTC offset of 8 hours instead of the expected DST offset of 7 hours, so the time ends up not being saved correctly.
What options do I have for converting a naive datetime to the correct tzinfo PDT (or other DST time response)?
(Also, note that not all users live in a time zone that monitors DST, or can live in a time zone that switches at different times, so in order to make a decision, such as timedelta correction, before saving, I will need to find out if the time zone supports DST and what dates it switches to).