【问题标题】:How to create a datetime aware for Django in UTC如何在 UTC 中为 Django 创建日期时间感知
【发布时间】:2016-09-02 07:08:00
【问题描述】:

我已经在设置中配置了我的时区,如 America/Guatemala 并且我的模型中有一些日期时间字段,我正在使用 default=timezone.now 但它没有保存我的本地时间,即 UTC-6:00,是将其保存为 UTC-00:00。我无法更改它,因为现在数据库中以这种方式存储了一些重要数据。

我在检索查询集中的数据时遇到问题,我在request.POST 中发送一个字符串,如下所示:

date='1/09/2016'

我已经尝试这个来配置我的查询日期:

f=date.split('/') 
if len(f)>1:
    initialdate=datetime.datetime(int(f[2]),int(f[1]),int(f[0]),0,0,0,tzinfo=pytz.UTC)
    finaldate=datetime.datetime(int(f[2]),int(f[1]),int(f[0]),23,59,59,tzinfo=pytz.UTC)

这是我的查询集:

sale=Sale.objects.filter(Q(pk=int(cod))|Q(sale_date__range=(initialdate,finaldate)))

但由于我保存的数据与我的本地日期和时间之间存在 6 小时的差异,如果我在本地时间下午 6:01 存储销售,则保存的数据将存储为明天上午 00:01。如果我想查看今天的所有销售额,它不会显示下午 6 点之后的销售额,因为它们保存在不同的日期。

我有另一个查询,我发送两个不同的日期,我使用相同的代码,我只是将时间 0,0,0 添加到第一个日期,并将 23,59,59 添加到第二个日期,但我有同样的问题。

我的问题是,如何将这六个小时添加到我用作参数的日期中?我需要知道日期时间,而且我无法更改模型中的任何内容,我只能更改发送到查询集的参数。

【问题讨论】:

  • 这不是您问题的直接答案,但在阅读这篇博文之前,我一直在与时区格式和数学作斗争。希望它对您也有帮助:(Pytz 和 Django 中的时区 | tommikaikkonen.github.io/timezones

标签: django datetime


【解决方案1】:

我也有这个问题。我所做的是: 一整天的日期范围是:00:00:00 - 23:59:59,这是本地日期时间,但是数据库中的日期时间已经转换为UTC,所以我只是将本地日期时间分6小时,你可以这样做;

import datetime

f=date.split('/') 
if len(f)>1:
    initialdate=datetime.datetime(int(f[2]),int(f[1]),int(f[0]),0,0,0,tzinfo=pytz.UTC)
    finaldate=datetime.datetime(int(f[2]),int(f[1]),int(f[0]),23,59,59,tzinfo=pytz.UTC)
    initialdate = initialdate - datetime.timedelta(hours=6)
    finaldate = finaldate - datetime.timedelta(hours=6)

【讨论】:

    【解决方案2】:
    import pytz
    from django.utils import timezone
    
    initialdate = datetime.datetime.combine(date, datetime.time.min.replace(tzinfo=timezone.UTC())).astimezone(pytz.timezone('America/Guatemala'))
    
    finaldate = datetime.datetime.combine(date, datetime.time.max.replace(tzinfo=timezone.UTC())))).astimezone(pytz.timezone('America/Guatemala'))
    

    【讨论】:

    • 我试过你的代码,从今天的最小和最大小时数计算需要六个小时,但是有一个问题,在我本地时间是 9 月 12 日 22:11 小时,服务器有 4 个: 9 月 13 日的 11 个小时,所以它有额外的一天。进行 substarction 时,它会在 initialdate= 9 月 12 日 18:00 和 finaldate= 9 月 13 日 18:00 给我。所以,如果在我当地时间下午 4 点进行销售,我想查看今天的销售情况晚上 10 点,我只能看到晚上 18:00 之后的销售额,之前的销售额没有显示。我该如何解决这个问题?
    • 你的 Django 版本是什么?从 1.9 版开始,django 具有 date 字段查找 (docs.djangoproject.com/el/1.10/ref/models/querysets/#date)。在这种情况下,你可以这样做 Sale.objects.filter(sale_date__date=initialdate) where initialdate=timezone.now().astimezone(pytz.timezone('America/Guatemala')).date() 你的数据库是什么?
    • 或者你可以取你的本地时间,把它转换成服务器时区,然后结合 time.min / time.max.
    【解决方案3】:

    已编辑以显示日期

    要简单地将日期更改为六小时前,您可以使用datetimetimedelta

    要更改查询中的 sale_date 对象,您只需执行以下操作:

    import datetime
    import pytz
    for s in sale:
        sale_date = sale_date - datetime.timedelta(hours=6)
        sale_date = sale_date.replace(tzinfo=pytz.timezone("America/Guatemala"))
        s.save()
    

    要更改所有Sale 对象中的sale_date

    import datetime
    import pytz
    all_sales =  Sale.objects.all()
    for sale in all_sales:
        sale_date = sale_date - datetime.timedelta(hours=6)
        sale_date = sale_date.replace(tzinfo=pytz.timezone("America/Guatemala"))
        sale.save()
    

    另外,要解析包含时间信息的字符串,请使用strptime:

    import datetime
    date='1/09/2016'
    parsed_date = datetime.datetime.strptime(date, '%w/%m%Y')
    

    更多信息here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-27
      • 2016-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多