【问题标题】:Display a time using a given timezone in Django在 Django 中使用给定时区显示时间
【发布时间】:2016-07-15 14:06:33
【问题描述】:

我正在开发一个用于记录潜水的 Django 应用程序,每次潜水都有一个日期时间和一个时区。我正在使用 django-timezone-field 应用程序作为时区。

class Dive(models.Model):
  ...
  date_time_in = models.DateTimeField(default=timezone.now)
  timezone = TimeZoneField(default=timezone.get_current_timezone_name())

所以用户可以输入一个日期时间字符串(“2016-07-11 14:00”)并选择一个时区(“亚洲/曼谷”-UTC+0700),然后我将日期时间的时区设置为在我看来是这样的:

def log_dive(request):
  if request.method == 'POST':
    form = DiveForm(request.POST)
    if form.is_valid():
      dive = form.save(commit=False)
      date = dive.date_time_in
      date = date.replace(tzinfo=None)
      dive.date_time_in = dive.timezone.localize(date)
      dive.save()

然后数据库将日期时间作为 UTC 存储在数据库中(SELECT 语句在我的本地时区中给出):

# SELECT date_time_in, timezone FROM divelog_dive ORDER BY number DESC;
      date_time_in      |     timezone     
------------------------+------------------
 2014-07-11 17:00:00+10 | Asia/Bangkok

现在有两件事我正在努力解决:

1) 我想显示给定时区的日期,但我似乎无法阻止它默认为 TIME_ZONE 设置。

2) 如果用户编辑记录,编辑字段中显示的时间应该是他们最初输入的时间(14:00),而不是显示在当前时区(17:00)。

【问题讨论】:

    标签: python django datetime timezone-offset


    【解决方案1】:

    settings.py中检查您的时区设置

    【讨论】:

      【解决方案2】:

      您的设置文件中有 USE_TZ = true 吗?如果您使用 djangoadmin-startproject 命令创建应用,则默认设置。

      此外,我在上一份工作中遇到了时区问题,但发现使用 pytz 确实有帮助。你试过那个包了吗?

      编辑:好吧,伙计,我可能离题了,但是由于没有其他人回答并且我感到时区在挣扎,所以我注意到了一些事情......

      您将日期对象替换为 tz_info=None,但您不想将其替换为数据库中的时区吗?所以你会得到那个时区并使用有效的格式(tzinfo=blah ...)进行替换? 就像我说的那样,我可能会走得更远,但如果这对你有帮助的话。

      【讨论】:

      • 感谢您的帮助,克里斯,我现在已经弄清楚了,我发布的代码对于存储日期时间是正确的,replace(tzinfo=None) 之后的行将时区设置为用户选择的时区( dive.timezone 是 pytz 时区对象)。
      【解决方案3】:

      抱歉,我认为我没有很好地解释我的问题。我终于想通了,所以我会回答我自己的问题。

      1) 结果很简单,Django 有一个模板标签用于显示给定区域中的时间:

      {{ dive.date_time_in|timezone:dive.timezone|date:"Y-m-d H:i e" }}
      

      对于 2),我遇到了 [1],这导致我找到了这个解决方案:在视图中,从数据库中获取对象后,我使用 astimezone(...) 转换日期值(数据库存储作为UTC)到给定的时区。然后我使用 replace(tzinfo=None) 使它变得幼稚,然后它在我的表单上正确显示。

      def edit_dive(request, dive_id=None):
        dive = None
        if dive_id != None:
          dive = get_object_or_404(Dive, pk=dive_id)
          local_date = dive.date_time_in.astimezone(timezone(str(dive.timezone)))
          dive.date_time_in = local_date.replace(tzinfo=None)
      

      [1]http://www.saltycrane.com/blog/2009/05/converting-time-zones-datetime-objects-python/

      【讨论】:

        猜你喜欢
        • 2017-08-25
        • 1970-01-01
        • 1970-01-01
        • 2020-10-14
        • 2019-12-19
        • 2023-04-01
        • 2018-01-27
        • 2019-05-11
        相关资源
        最近更新 更多