cansadadeserfeliz
cansadadeserfeliz

Reputation: 3133

How to show datetime in Django in specific timezone?

I have a Django (v1.10.6) project that has some models with datetime fields, for example:

created_at = models.DateTimeField(auto_now_add=True)

that are stored in PostgreSQL database without timezone information:

created_at timestamp without time zone NOT NULL

postgresql.conf:

timezone = 'UTC'

I want all the dates of my application to be shown in America/Bogota time zone (it shouldn't depend on user's actual time zone), so my settings.py file has the following configuration:

TIME_ZONE = 'America/Bogota'
USE_I18N = False
USE_L10N = True
USE_TZ = True

SHORT_DATETIME_FORMAT = 'd-m-Y H:i:s'
SHORT_DATE_FORMAT = 'd-m-Y'
TIME_FORMAT = 'H:i:s'

but when I write

{{ object.created_at|date:'SHORT_DATETIME_FORMAT' }}

in templates, it still shows the date in UTC format.

Update:

I added the following middleware, but it didn't help:

class TimezoneMiddleware(MiddlewareMixin):
    def process_request(self, request):
        timezone.activate(pytz.timezone(settings.TIME_ZONE))

Update 2:

It works the following way:

import pytz
from django.utils import timezone

timezone.is_naive(object.created_at)  # True
object.created_at.replace(tzinfo=timezone.utc)

(forcing the date to be in UTC timezone and then passing it to template without localize filter) but I don't understand why Django still returns naive datetime when USE_TZ is set to True.

Upvotes: 4

Views: 9534

Answers (5)

Amna Kassim
Amna Kassim

Reputation: 1

In the settings.py file

change TIME_ZONE = 'Asia/Baghdad' to your time zone name of your country.

Upvotes: 0

Arun Baby
Arun Baby

Reputation: 11

You can create a middleware and use activate function to set a specific time zone.

middleware.py

import pytz
import requests

from django.utils import timezone

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

def __call__(self, request):
    
    tzname = 'America/Bogota'
    if tzname:
        timezone.activate(pytz.timezone(tzname))
    else:
        timezone.deactivate()
    return self.get_response(request)

settings.py

MIDDLEWARE = [      ........
            'projectname.middleware.TimezoneMiddleware',
]

Upvotes: 1

Inti
Inti

Reputation: 3751

You need to select the current timezone.

You should set the current time zone to the end user’s actual time zone with activate(). Otherwise, the default time zone is used.

Some relevant extracts from the docs below.

The default time zone is the time zone defined by the TIME_ZONE setting.

The current time zone is the time zone that’s used for rendering.

You should set the current time zone to the end user’s actual time zone with activate(). Otherwise, the default time zone is used.

From: https://docs.djangoproject.com/en/1.10/topics/i18n/timezones/#default-time-zone-and-current-time-zone

I recommend having all the datetime's stored internally in UTC so setting TIME_ZONE = 'UTC' in your settings.py and then switching the current timezone to the timezone you wish output to be in. This will make it much easier for you to add further timezones later and will make any date or time arithmetic much easier especially if you have to consier any daylight savings time changes. If you really don't need it maybe it is easier to disable the timezones completely.

Upvotes: 1

Hannan
Hannan

Reputation: 55

Try django-datetime-widget and use configurations:

If you want to use localization:

  • Set USE_L10N = True, USE_TZ = True and USE_I18N = True in settings.py
  • Add 'django.middleware.locale.LocaleMiddleware' to MIDDLEWARE_CLASSES in settings.py
  • When you create the widget add usel10n = True like attribute : DateTimeWidget(usel10n=True)

Link is here:

https://github.com/asaglimbeni/django-datetime-widget

Upvotes: 0

XaviP
XaviP

Reputation: 188

{% load tz %}
{{ value|localtime }}

https://docs.djangoproject.com/en/1.10/topics/i18n/timezones/#template-filters

Upvotes: 0

Related Questions