I have a django application and it stores in the database (postgres) the datetimes in UTC, it has users worldwide.
But in the application logic, I have some validations according to local time ranges, i.e. the user is on Guayaquil and some thing happens all sunday; I'm having issues to perform it and doing some debugging I found that in UTC is monday at 2AM at but the user (America/Guayaquil) UTC-5 is still on sunday 21:00. So it fails for the user because the DAY changed.
I am thinking of storing the user timezone in the user table but I don't know how to set it and how to prevent the previous scenario.
As a side question, how can I convert a UTC datetime stored in the database to the user's timezone for (example) email notification. (I'm not going to send him an email with datetime and timezone for him to do the math in his mind).
That is good you are storing everything in
UTC
. Now you don't need to store the user timezone in database what you can do is that on login page you can calculate the user offset fromUTC
and store in session vi ajax. Here is the simple script you can include in your login page template:Add this url in your root urls.py:
Add this view:
Now you have user timezone offset in session. Now comes the part for calculation. You need these two simple helper functions:
Ok if you want to show the user time according to the his/her timezone you would do:
If you have datetime or date coming from the form and you want to validate it e.g. the date chosen should not be less than current date you would do:
The benefit of this approach is that you don't need to ask users to specify their timezones. We are doing everything automatically on our side.
Default django is take America/Chicago time zone. Best way you need to store the User time zone in database and whenever user login take the time zone from DB and change the configuration via code.
https://docs.djangoproject.com/en/dev/ref/settings/#time-zone
The global strategy in django is to use UTC in persistence layer and use local time when interacting with the end user (you can have a look here. Consequently in your use case I would persist time in UTC in the db and use the current time zone for processing the calculation you need.
The timezone selection function are here . With get_current_timezone() you get the tzinfo object.
The current timezone is the one that is used for the rendering of the web page. It might not be the one you want, whether the user for instance wants to use a UTC-1 timezone but is currently seeing the web page in UTC+1. In this situation, it is better for you to keep the timezone in the session in a similar approach as explained by Aamir or to persist it.
The approach for persistence in model merely to use a CharField and put the timezone string you can get using the pytz package.