简体   繁体   English

在 django 中获取本地时区

[英]Get local timezone in django

I have a mysql DATETIME value that is stored in system time, UTC.我有一个 mysql DATETIME值,它存储在系统时间 UTC 中。 I need to convert that to my local timezone in django.我需要将其转换为 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"?如何让 last_updated 值位于我的本地时区 =“美国/洛杉矶”?

The Django documentation for timezones documents all the necessary details for converting datetime objects to the appropriate time zone for display. 时区Django文档记录了将datetime对象转换为适当时区以显示的所有必要细节。

Your data is stored in UTC which is good. 您的数据以UTC格式存储,这很好。 When you obtain a DateTime field object from the database it will be a naive datetime.datetime object. 从数据库获取DateTime字段对象时,它将是一个天真的datetime.datetime对象。 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 . 您的webapp用户可能位于不同的时区,因此必须为每个请求转换为适当的时区。 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: 如果你安装了pytz,你应该能够做到以下几点:

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. 如果您只有一个想要设置时区的天真datetime.datetime实例,那么只需直接使用pytz模块即可。 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)

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. tzinfo属性显示为utc,但日期和时间显示正确。

UPDATE 30/10/2015 (Django 1.8) 更新30/10/2015 (Django 1.8)

I'm using another approach today, that is more django friendly 我今天正在使用另一种方法,那就是django友好

>>> 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>)

localtime is a template filter, this may be helpful. localtime是模板过滤器,这可能会有所帮助。

https://github.com/django/django/blob/1.8.4/django/utils/timezone.py#L298 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)

I've created a simple middleware to handle all of this stuff for you: 我已经创建了一个简单的中间件来为您处理所有这些内容:

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

Simply install it and follow the instructions and you're done! 只需安装它并按照说明完成即可!

  1. Install django-easy-timezones 安装django-easy-timezones

     pip install django-easy-timezones pytz pygeoip 
  2. Add "easy-timezones" to your INSTALLED_APPS setting like this: 将“easy-timeZones”添加到您的INSTALLED_APPS设置中,如下所示:

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

     MIDDLEWARE_CLASSES = ( ... 'easy-timezones.middleware.EasyTimezoneMiddleware', ) 
  4. Add a path to the MaxMind GeoIP database in your settings file: 在设置文件中添加MaxMind GeoIP数据库的路径:

     GEOIP_DATABASE = '/path/to/your/geoip/database/GeoIP.dat' 
  5. Enable localtime in your templates. 在模板中启用localtime。

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

I have came to the same problem. 我遇到了同样的问题。 In my settings, I have set the TIME_ZONE , but the time in MySql still UTC time. 在我的设置中,我设置了TIME_ZONE ,但MySql中的时间仍然是UTC时间。

# settings.py
TIME_ZONE = 'Asia/Shanghai'

Then I found,in settings.py, USE_TZ has be set to False 然后我发现,在settings.py中, USE_TZ已设置为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. 正如@MagicLAMP所指出的那样,它仅适用于单个时区网站,如果您的网站是国际网站,或者如果您的网站使用了夏令 ,请检查时区

I personally would advice against using a TIME_ZONE setting other than UTC. 我个人建议不要使用UTC以外的TIME_ZONE设置。 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. 我记得过去有这个问题,不管数据库是在不同的时区运行(在不同的时区保存值),而不是Django后端使用的。 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. 一个好的做法通常是在后端使用一个时区(比如说UTC)并将前端的时间转换为你服务的用户时区。

1: Define the timezone in your view 1:在视图中定义时区

from django.utils import timezone

variable = timezone.now()

2: Then use it in your template 2:然后在模板中使用它

{% load l10n %}

Teresina, {{variable |localize}}.

只是用

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: 我想用户的IP地址时区然后在Django 2及更高版本中执行此操作:

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

I have found easy solution based on custom template filter .我找到了基于自定义模板过滤器的简单解决方案。

Here is my settings.py :这是我的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 :在我名为 Marker 的 model 中,我将日期时间保存为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接下来,我使用路径project/app/templatetags/some_file_name.py使用自定义模板过滤器创建一个新的Python package

In some_file_name.py we do register a filter and write it's behavior:some_file_name.py我们确实注册了一个过滤器并写下它的行为:

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.因此,在我的情况下,日期时间保存在 DB 中,如我之前提到的2022-09-15 17:56:26.936210和过滤后,在模板中根据我的本地时区和日期格式显示为15.09.2022 20:56 .

Before filter: 2022-09-15 17:56:26.936210 After filter -> 15.09.2022 20:56过滤前: 2022-09-15 17:56:26.936210过滤后 -> 15.09.2022 15.09.2022 20:56

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM