【问题标题】:Handling per-object timezone settings in Django在 Django 中处理每个对象的时区设置
【发布时间】:2013-01-12 23:53:21
【问题描述】:

我有一个 Django 应用程序,用户可以在其中创建一个 Activity,然后为一个 Activity 创建多个日志条目。一个活动有一个创建的日期时间,一个日志条目也有一个创建的日期时间。

应使用创建用户在创建活动时的时区创建活动。具体来说,给定用户可能在不同的时区有两个活动;时区设置不是每个用户,而是每个活动。我可以在浏览器中的 JavaScript 中从 UTC 导出用户当前的偏移量(我很乐意依赖它)。

我不知道的是:如何将这些时间保存到数据库中,然后在渲染时正确显示?

我已打开 USE_TZ。在英国,一切正常:创建 Activity 时,我将创建的日期时间保存为 django.utils.timezone.now(),并将用户当前的偏移量(来自 JavaScript)保存为 Activity 中的 timezoneHoursOffset。然后,当我在页面上显示 Activity 及其日志条目时,我将其包装在 {% timezone "Etc/GMT+(timezoneHoursOffset)" %} ... {% endtimezone %} 中。

但是,如果服务器不在英国,则此方法不起作用。时间作为 UTC 保存在数据库中(我已经通过检查数据库本身而不是使用 ORM 来验证这一点),然后 ORM 将时间“更改”为比 UTC 晚八小时(因为服务器的时区是UTC-8) (这给出了正确的时间!)然后{% timezone %} 标签减去 another 八小时的时间,这意味着显示的时间比它应该的时间晚了八小时。

我不确定我是否应该以不同的方式节省时间;在输出时更改它们;使用时区模板标签;或者是其他东西。这东西很混乱。你会建议我如何处理这种情况?

【问题讨论】:

    标签: django timezone


    【解决方案1】:

    Ref the answer,“Etc/GMT”时区的符号颠倒了。例如,我在+0800,应该是'Etc/GMT-8'而不是'Etc/GMT+8'(我怀疑你的UTC-8实际上应该是"Etc/GMT+8"):

    >>> from django.template import Template, Context
    >>> from django.utils.timezone import now
    >>> print(Template("""{% load tz %}
    localtime: {{ t }}
    Etc/GMT-8: {{ t|timezone:"Etc/GMT-8" }}
    Etc/GMT+8: {{ t|timezone:"Etc/GMT+8" }}
    """).render(Context({'t':now()})))
    
    localtime: Jan. 29, 2013, 11:48 p.m.
    Etc/GMT-8: Jan. 29, 2013, 11:48 p.m.
    Etc/GMT+8: Jan. 29, 2013, 7:48 a.m.
    

    所以,你必须反转你的timezoneHoursOffset...

    对于DB存储,根据the doc,最好以UTC格式存储数据。

    此外,由于 DST,您需要确保您的 javascript 生成正确的小时偏移量。如果可以的话,最好存储时区名称并相应地使用它。

    【讨论】:

      【解决方案2】:
      from datetime import datetime
      from dateutil import zoneinfo
      
      from_zone = zoneinfo.gettz('UTC')
      to_zone = zoneinfo.gettz('UK/UK') 
      
      utc = created # your datetime object from the db
      
      # Tell the datetime object that it's in UTC time zone since 
      # datetime objects are 'naive' by default
      utc = utc.replace(tzinfo=from_zone)
      
      # Convert time zone
      eastern_time = utc.aztimezone(to_zone)
      

      【讨论】:

      • 这将为整个会话设置时区。如果我在一个页面上显示多个 Activity,那么它们可能有不同的时区,因此它们需要以不同的方式显示。
      • 那么您必须为此创建设置。允许用户保存自己的时区。您可以使用上面的代码来保存时区。我也这样做了,我允许我的用户自己选择。
      • 啊,正是我要避免的是每个用户都有时区;他们是每个活动。一个给定的用户可能在不同的时区有两个活动;没有一个时区适用于用户的所有活动。
      猜你喜欢
      • 2016-01-13
      • 1970-01-01
      • 2017-06-17
      • 2018-12-18
      • 1970-01-01
      • 1970-01-01
      • 2013-10-30
      • 1970-01-01
      • 2015-06-01
      相关资源
      最近更新 更多