在 django 中获取本地时区

问题描述 投票:0回答:12

我有一个 mysql

DATETIME
值,存储在系统时间 UTC 中。我需要将其转换为 django 中的本地时区。这是我目前拥有的:

# 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

我如何获得我当地时区=“美国/洛杉矶”的last_updated值?

python django
12个回答
48
投票

Django 时区文档记录了将

datetime
对象转换为适当的时区以进行显示的所有必要细节。

您的数据存储在 UTC 中,这很好。 当您从数据库获取

DateTime
字段对象时,它将是一个简单的
datetime.datetime
对象。 即不附加时区的日期/时间。 然后由您来进行转换。

您的网络应用程序的用户可能位于不同的时区,因此必须针对每个请求转换到适当的时区。 这就是为什么有一个 activate 功能来设置当前时区。

如果您安装了pytz,您应该能够执行以下操作:

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

模板引擎中日期字段的所有输出都会自动将您的原始日期时间对象转换为正确的时区以进行显示。

如果您只有一个简单的

datetime.datetime
实例想要设置时区,那么只需直接使用
pytz
模块即可。 不过,在您的视图中这样做并不正常,因为最好只在演示时转换时区。

from pytz import timezone

settings_time_zone = timezone(settings.TIME_ZONE)
last_updated = last_updated.astimezone(settings_time_zone)

36
投票

哭了很多次之后,我可以通过这样做来显示我的国家的正确日期:

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

tzinfo
属性显示的是UTC,但日期和时间显示正确。

更新 30/10/2015(Django 1.8)

我今天使用另一种方法,对 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>)

19
投票

localtime是一个模板过滤器,这可能会有所帮助。

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

代码示例:

from django.utils.timezone import localtime 

desired_datetime = localtime(stored_datetime)

9
投票

我个人建议不要使用 UTC 以外的

TIME_ZONE
设置。我记得过去遇到过这个问题,因为数据库在与 Django 后端使用的不同时区运行(在不同时区保存值)。这意味着比较时间会很麻烦,根据你在做什么来来回改变时间。

一种好的做法通常是在后端使用一个时区(比如说 UTC),并将前端的时间转换为您所服务的用户时区。


7
投票

我创建了一个简单的中间件来为您处理所有这些事情:

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

只需安装并按照说明操作即可完成!

  1. 安装 django-easy-timezones

    pip install django-easy-timezones pytz pygeoip
    
  2. 将“easy-timezones”添加到您的 INSTALLED_APPS 设置中,如下所示:

    INSTALLED_APPS = (
    ...
    'easy-timezones',
    )
    
  3. 将 EasyTimezoneMiddleware 添加到您的 MIDDLEWARE_CLASSES

    MIDDLEWARE_CLASSES = (
    ...
    'easy-timezones.middleware.EasyTimezoneMiddleware',
    )
    
  4. 在您的设置文件中添加MaxMind GeoIP 数据库的路径:

    GEOIP_DATABASE = '/path/to/your/geoip/database/GeoIP.dat'
    
  5. 在模板中启用当地时间。

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


5
投票

只需使用

timezone.localtime(arg)

5
投票

我也遇到了同样的问题。在我的设置中,我设置了

TIME_ZONE
,但是MySql中的时间仍然是UTC时间。

# settings.py
TIME_ZONE = 'Asia/Shanghai'

然后我发现,在settings.py中,

USE_TZ
已设置为False

USE_TZ = False

正如 @MagicLAMP 所指出的,它仅适用于单时区网站,如果您的网站是国际网站或者您的网站所在的地方是否实行夏令时,请检查时区


4
投票

我花了一段时间才找到这个问题,但这就是我解决它的方法。我从 IP 地址猜测用户的时区,然后在 Django 2 及更高版本中执行此操作:

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

1
投票

1:定义您视图中的时区

from django.utils import timezone

variable = timezone.now()

2:然后在你的模板中使用它

{% load l10n %}

Teresina, {{variable |localize}}.

0
投票

我找到了基于自定义模板过滤器的简单解决方案。

这是我的

settings.py

TIME_ZONE = 'UTC'
USE_L10N = True
USE_TZ = True

在名为 Marker 的模型中,我将日期时间保存为

2022-09-15 17:56:26.936210
:

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

接下来,我使用路径创建一个新的 Python 包,其中包含自定义模板过滤器

project/app/templatetags/some_file_name.py

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

接下来使用代码在模板中加载我们的过滤器:

{% load some_file_name %}

最后将过滤器应用于项目:

{{ marker.created_at|to_user_tz_short }}

因此,就我而言,日期时间保存在数据库中,正如我之前提到的,如

2022-09-15 17:56:26.936210
,过滤后,在模板中,根据我的本地时区和日期格式,它显示为
15.09.2022 20:56

过滤前:

2022-09-15 17:56:26.936210
过滤后 ->
15.09.2022 20:56


0
投票

我使用时间模块在用户主页上设置本地时区

timely = time.time() text = time.ctime(timely) context = {'time':text} render(request, 'home.html',context)


0
投票

要从 Django 获取时区对象,而不安装任何新的库,如

pytz
,你可以这样做:

import django.utils.timezone
djangoTimeZone = django.utils.timezone.get_current_timezone()

这可以作为

tzinfo
传递到
datetime
对象中,例如:

import datetime
myDateTime = datetime.datetime(year=2030, month=1, day=2, hour=4, minute=24, tzinfo=djangoTimeZone)
© www.soinside.com 2019 - 2024. All rights reserved.