Datetime Internationalization in Django

JunePyo Suh·2020년 9월 22일
0

Referenced articles:
(1) spoqa
(2) Django timezone documentation
(3) Find time difference between two datetime objects

Naive datetime

only stores date / time information

import datetime

datetime.datetime.utcnow()
# UTC based naive datetime : datetime.datetime(2019, 2, 15, 4, 54, 29, 281594)

datetime.datetime.now()
# local environment based naive datetime : datetime.datetime(2019, 2, 15, 13, 54, 32, 939155)

Aware datetime

Additionally stores timezone info

import datetime
from pytz import utc

utc.localize(datetime.datetime.utcnow())
# UTC based aware datetime : datetime.datetime(2019, 2, 15, 4, 55, 3, 310474, tzinfo=<UTC>)

Rule of thumb

Do not use naive datetime

Mixing naive and aware datetimes may lead to unintended bugs. isinstance() is not enough to differentiate these two, so just don't use naive datetime.

Aware datetime (that needs to be stored in DB for a long time) should always be based on UTC

Perform all internal computations and comparisions in UTC. Should you return datetime information to your clients, convert aware datetime information to local time zone at the end of the process.

Selecting the current time zone

Here is an example of storing the current timezone in session from django timezone documentation.

// Add the following middleware to MIDDLEWARE
import pytz

from django.utils import timezone

class TimezoneMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        tzname = request.session.get('django_timezone')
        if tzname:
            timezone.activate(pytz.timezone(tzname))
        else:
            timezone.deactivate()
        return self.get_response(request)

// Create a view that sets the current timezone
from django.shortcuts import redirect, render

def set_timezone(request):
    if request.method == 'POST':
        request.session['django_timezone'] = request.POST['timezone']
        return redirect('/')
    else:
        return render(request, 'template.html', {'timezones': pytz.common_timezones})

How can I obtain the local time in the current time zone?

As mentioned above, there really is no need to obtain local time. Python knows how to compare aware datetimes, taking into account UTC offsets when necessary. Therefore, you should try to write all your model and view code in UTC. Then only when you are returning the time as the final output to humans, you could do:

>>> from django.utils import timezone
>>> timezone.localtime(timezone.now())
datetime.datetime(2012, 3, 3, 20, 10, 53, 873365, tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>)

0개의 댓글