ae-utbm / sith

🌐 The website of the AE
https://ae-utbm.github.io/sith/
GNU General Public License v3.0
6 stars 4 forks source link

Fix timezone shifts in news/posters/etc. (every forms.DateTimeField) - [closed] #386

Closed Juknum closed 2 years ago

Juknum commented 4 years ago

In GitLab by @tleb on Apr 17, 2020, 22:38

Merges datetime-hell -> master

The broken behaviour that was previously observed and that this MR tries to fix:

  1. Create a news at /com/news/create with start date 2020-04-17 20:00:00 and end date 2020-04-17 22:00:00.
  2. On /com/news/admin it gets displayed correctly.
  3. However, if you edit it at /com/news/:id/edit it show 2020-04-17 18:00:00 and 2020-04-17 20:00:00 as start and end dates (assuming the current timezone is UTC+2).
  4. If you submit which touching anything, the event/news/poster/other gets shifted by 2h (because it's summer time, only 1h if it's winter).

Timezone issue! What I understood from a (loooooong) debugging session (and django's doc) is that the database stores the datetime as UTC (2020-04-17 18:00:00 in our case). When it is displayed in a template, we use the localtime filter to adjust to the current timezone. However, a forms.DateTimeField is passed the datetime to display as a string. It was initially displayed as is (coming from the database) and therefore the UTC value was displayed. To solve this, the value which comes from the database must be parsed into a datetime to adjust the timezone.

It is done in three steps in the prepare_value(self, value) method which is used to prepare the database value to be displayed in the form (this MR changes nothing for the form validation and database insertion steps):

  1. django.utils.dateparse.parse_datetime(string_dt), which returns a naive datetime storing the UTC time.
  2. django.utils.timezone.make_aware(naive_dt, timezone.utc) which turns the naive datetime into an aware datetime which is "located" in UTC.
  3. django.forms.utils.to_current_timezone(aware_dt) which turns an aware datetime into a naive datetime with the datetime which corresponds in the current timezone.

Example usage:

>>> from django.utils.dateparse import parse_datetime
>>> from django.utils import timezone
>>> from django.forms.utils import to_current_timezone

>>> parse_datetime("2020-04-17 18:00:00")
datetime.datetime(2020, 4, 17, 18, 0)
>>> timezone.make_aware(_, timezone.utc)
datetime.datetime(2020, 4, 17, 18, 0, tzinfo=<UTC>)
>>> to_current_timezone(_)
datetime.datetime(2020, 4, 17, 20, 0)

It is then turned back into a string to be displayed. It's important because otherwise it is automatically converted using the locale and on my PC it becomes 17/04/2020 20:00:00 (I'd say it's django's settings and not GNU/Linux's locale setting because mine is en_US.UTF-8) and the front-end doesn't support this format (the backend neither btw).

It's a WIP because I would like to have opinions on the approach and it needs to be tested by other people! An exhaustive list of pages this MR concerns:

I await (async hehe) your reviews. :)

Juknum commented 4 years ago

In GitLab by @tleb on Apr 17, 2020, 22:40

An aside: is core/templates/core/poster_list.jinja ever used? A global search brings up nothing. It seems like a duplicate (not exactly the same though) to com/templates/com/poster_list.jinja.

Juknum commented 4 years ago

In GitLab by @tleb on Apr 18, 2020, 08:56

added 1 commit

Compare with previous version

Juknum commented 4 years ago

In GitLab by @tleb on Apr 18, 2020, 13:18

fixes #102

Juknum commented 4 years ago

In GitLab by @sli on Apr 20, 2020, 18:29

Really nice job ! I was thinking, since we are making a wrapper in core, why also not harmonizing the input format so we don't have this wierd copy and paste all over the codebase :)

Juknum commented 4 years ago

In GitLab by @tleb on Apr 21, 2020, 08:47

added 1 commit

Compare with previous version

Juknum commented 4 years ago

In GitLab by @tleb on Apr 21, 2020, 08:49

Done! I did it through default values in the constructor.

Juknum commented 4 years ago

In GitLab by @tleb on Apr 21, 2020, 09:00

added 1 commit

Compare with previous version

Juknum commented 4 years ago

In GitLab by @sli on Apr 21, 2020, 17:57

Commented on core/views/forms.py line 409

You can also do

def __init__(self, input_formats=["format"], widget=SelectDateTime, **kwargs):
Juknum commented 4 years ago

In GitLab by @sli on Apr 21, 2020, 17:58

Except for my last comment, really nice job, if you could rename your commit to match our pseudo naming convention that would be nice (module_touched1/module_touched2: change).

Juknum commented 4 years ago

In GitLab by @sli on Apr 22, 2020, 23:16

Moved to https://ae-dev.utbm.fr/ae/Sith/-/merge_requests/270

Juknum commented 4 years ago

In GitLab by @sli on Apr 22, 2020, 23:16

closed

Juknum commented 3 years ago

In GitLab by @skia on Sep 29, 2021, 15:53

mentioned in commit 007157e2e8aae7b2313614a65805b27090e6dffd