【问题标题】:How to show datetime in Django in specific timezone?如何在特定时区的 Django 中显示日期时间?
【发布时间】:2017-08-25 22:20:24
【问题描述】:

我有一个 Django (v1.10.6) 项目,其中包含一些带有日期时间字段的模型,例如:

created_at = models.DateTimeField(auto_now_add=True)

存储在没有时区信息的 PostgreSQL 数据库中:

created_at timestamp without time zone NOT NULL

postgresql.conf:

timezone = 'UTC'

我希望我的应用程序的所有日期都显示在America/Bogota 时区(它不应该取决于用户的实际时区),所以我的settings.py 文件具有以下配置:

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'

但是当我写的时候

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

在模板中,它仍然以UTC 格式显示日期。

更新:

我添加了以下中间件,但没有帮助:

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

更新 2:

它的工作方式如下:

import pytz
from django.utils import timezone

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

(强制日期在UTC 时区,然后将其传递给没有localize 过滤器的模板)但我不明白为什么当USE_TZ 设置为True 时Django 仍然返回天真的日期时间。

【问题讨论】:

    标签: django timezone django-timezone


    【解决方案1】:

    您需要选择当前时区。

    您应该使用 activate() 将当前时区设置为最终用户的实际时区。否则,使用默认时区。

    以下文档的一些相关摘录。

    默认时区是 TIME_ZONE 设置定义的时区。

    当前时区是用于渲染的时区。

    您应该使用 activate() 将当前时区设置为最终用户的实际时区。否则,使用默认时区。

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

    我建议将所有 datetime 存储在 UTC 内部,因此在 settings.py 中设置 TIME_ZONE = 'UTC',然后将当前时区切换到您希望输出所在的时区。这将使您稍后可以添加更多时区,这将使任何日期或时间算术变得更加容易,特别是如果您必须考虑任何夏令时更改。 如果你真的不需要它,也许完全禁用时区会更容易。

    【讨论】:

    • The current time zone is the time zone that’s used for rendering。我想在America/Bogota 时区进行渲染,所以我设置了TIME_ZONE = 'America/Bogota' 并在内部以UTC 存储日期时间。问题是它仍然在 UTC 中渲染
    • @vero4ka TIME_ZONE 设置存储“默认时区”而不是“当前时区”。要启用当前时区,您需要使用上面链接的文档中描述的当前时区调用activate()
    • 我在settings.py 中写了timezone.activate(TIME_ZONE),但没有帮助
    • @vero4ka 您需要为每个请求执行此操作。见:docs.djangoproject.com/en/1.10/topics/i18n/timezones/…
    • 我试过了,但看起来它不起作用,因为 Django 返回 naive 日期时间,而不是 UTC 中的 aware 日期时间:timezone.is_naive(object.created_at) -> True即使USE_TZ 设置为True,所以localize 不会返回正确的日期时间。
    【解决方案2】:

    您可以创建一个中间件并使用activate 函数来设置特定的时区。

    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',
    ]
    

    【讨论】:

      【解决方案3】:

      【讨论】:

      • 我想要一个具有特定时区的全局设置,而不是在每个模板中写|localtime
      • 那也许你可以在视图中设置。
      【解决方案4】:

      尝试 django-datetime-widget 并使用配置:

      如果你想使用本地化:

      • 在 settings.py 中设置 USE_L10N = True、USE_TZ = True 和 USE_I18N = True
      • 在 settings.py 中将“django.middleware.locale.LocaleMiddleware”添加到 MIDDLEWARE_CLASSES
      • 创建小部件时添加 usel10n = True 类似属性:DateTimeWidget(usel10n=True)

      链接在这里:

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

      【讨论】:

        【解决方案5】:

        settings.py 文件中

        TIME_ZONE = 'Asia/Baghdad' 更改为您所在国家/地区的时区名称。

        【讨论】:

          猜你喜欢
          • 2014-10-28
          • 2018-01-27
          • 2023-04-01
          • 2014-11-18
          • 1970-01-01
          • 1970-01-01
          • 2018-01-14
          • 2011-05-03
          相关资源
          最近更新 更多