Get local timezone in django

Question:

I have a mysql DATETIME value that is stored in system time, UTC. I need to convert that to my local timezone in django. Here is what I currently have:

# value in mysql
`timestamp`
2013-02-01 22:48:45

# settings.py
TIME_ZONE = 'America/Los_Angeles'

# views.py
last_updated = PathLastUpdated.objects.all()[0].timestamp
print last_updated
2013-02-01 22:48:45 <-- same as UTC

How would I get the last_updated value to be in my local timezone = “America/Los Angeles” ?

Asked By: David542

||

Answers:

I personally would advice against using a TIME_ZONE setting other than UTC. I remember having problems with this in the past, be it that the database was operating in a different timezone (saving values in a different timezone) than the Django backend was using. That meant a lot of hassle to compare the times, changing them forth and back depending on what you are doing.

A good practice is usually to use one timezone in the backend (lets say UTC) and convert the time in the frontend to the users timezone you are serving.

Answered By: Torsten Engelbrecht

The Django documentation for timezones documents all the necessary details for converting datetime objects to the appropriate time zone for display.

Your data is stored in UTC which is good. When you obtain a DateTime field object from the database it will be a naive datetime.datetime object. ie A date/time without a timezone attached. It’s then up to you to do the conversion.

User of your webapp may be in different time zones so the conversion to an appropriate time zone must occur for each request. This is why there is an activate function to set the current time zone.

If you have pytz installed you should be able to do the following:

from django.utils.timezone import activate
activate(settings.TIME_ZONE)

All output of date field in the template engine will then automatically convert you naive date time objects to the correct time zone for display.

If you just have a single naive datetime.datetime instance that you want to set the time zone on, then just use the pytz module directly. It is not normal to do this in your views though, as it’s a good idea to only convert the time zone at the point of presentation.

from pytz import timezone

settings_time_zone = timezone(settings.TIME_ZONE)
last_updated = last_updated.astimezone(settings_time_zone)
Answered By: Austin Phillips

I’ve created a simple middleware to handle all of this stuff for you:

https://github.com/Miserlou/django-easy-timezones

Simply install it and follow the instructions and you’re done!

  1. Install django-easy-timezones

    pip install django-easy-timezones pytz pygeoip
    
  2. Add “easy-timezones” to your INSTALLED_APPS setting like this:

    INSTALLED_APPS = (
    ...
    'easy-timezones',
    )
    
  3. Add EasyTimezoneMiddleware to your MIDDLEWARE_CLASSES

    MIDDLEWARE_CLASSES = (
    ...
    'easy-timezones.middleware.EasyTimezoneMiddleware',
    )
    
  4. Add a path to the MaxMind GeoIP database in your settings file:

    GEOIP_DATABASE = '/path/to/your/geoip/database/GeoIP.dat'
    
  5. Enable localtime in your templates.

    {% load tz %}
        The UTC time is {{ object.date }}
    {% localtime on %}
        The local time is {{ object.date }}
    {% endlocaltime %}
    
  6. Tada!

Answered By: Rich Jones

After cry a lot, I could show the correct date for my country doing something like this:

>>> from django.utils.timezone import get_current_timezone
>>> from front.models import Training

>>> tz = get_current_timezone()
>>> stored_date = Training.objects.first().start_date
datetime.datetime(2015, 4, 25, 17, 0, tzinfo=<UTC>)

>>> desired_date = stored_date + tz.utcoffset(stored_date)
datetime.datetime(2015, 4, 25, 14, 0, tzinfo=<UTC>)

The tzinfo attribute is shows utc, but the date and time is correct to show.

UPDATE 30/10/2015 (Django 1.8)

I’m using another approach today, that is more django friendly

>>> from django.utils import timezone
>>> from trainings.models import Training
>>> value = Training.objects.first().date

>>> value
datetime.datetime(2015, 10, 23, 11, 32, 54, 633151, tzinfo=<UTC>)

>>> timezone.localtime(value)
datetime.datetime(2015, 10, 23, 9, 32, 54, 633151, tzinfo=<django.utils.timezone.LocalTimezone object at 0x7fa6129784a8>)
Answered By: Fabio Montefuscolo

localtime is a template filter, this may be helpful.

https://github.com/django/django/blob/1.8.4/django/utils/timezone.py#L298

Code sample:

from django.utils.timezone import localtime 

desired_datetime = localtime(stored_datetime)
Answered By: Rex L

I have came to the same problem. In my settings, I have set the TIME_ZONE, but the time in MySql still UTC time.

# settings.py
TIME_ZONE = 'Asia/Shanghai'

Then I found,in settings.py, USE_TZ has be set to False

USE_TZ = False

As pointed out by @MagicLAMP, it only works for single time zone site, please check time-zones if your site is international or if daylight savings happen where your site is used.

Answered By: hereischen

Just use

timezone.localtime(arg)

It took me a while to find this, but this is how I solved it. I guess the user’s timezone from IP address and then do this in Django 2 and beyond:

{% load tz %}
{% timezone "Europe/Paris" %}
    Paris time: {{ object.date }}
{% endtimezone %}
Answered By: scott

1: Define the timezone in your view

from django.utils import timezone

variable = timezone.now()

2: Then use it in your template

{% load l10n %}

Teresina, {{variable |localize}}.
Answered By: Vanessa Martins

I have found easy solution based on custom template filter.

Here is my settings.py:

TIME_ZONE = 'UTC'
USE_L10N = True
USE_TZ = True

In my model named Marker I save datetime as 2022-09-15 17:56:26.936210:

class Marker(models.Model):
    ....
    created_at = models.DateTimeField(default=now, verbose_name="Date")

Next I create a new Python package with custom template filter using a path project/app/templatetags/some_file_name.py

In some_file_name.py we do register a filter and write it’s behavior:

from django import template
from django.utils.formats import date_format

register = template.Library()


@register.filter
def to_user_tz_short(dt):
    """Format UTC timestamp from DB to local user's short datetime format with appropriate timezone."""
    user_tz = date_format(
        dt.astimezone(), format="SHORT_DATETIME_FORMAT", use_l10n=True
    )
    return user_tz

Next load our filter in template with code:

{% load some_file_name %}

And finally apply filter to item:

{{ marker.created_at|to_user_tz_short }}

So, in my case the datetime is save in DB as I mentioned earlier like 2022-09-15 17:56:26.936210 and after filtering, in template it shows as 15.09.2022 20:56 according to my local time zone and date format.

Before filter: 2022-09-15 17:56:26.936210 After filter -> 15.09.2022 20:56

Answered By: Vitalii Mytenko
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.