如何在django中获取日期比较的本地时区日期时间

时间:2014-09-03 18:25:34

标签: python django date datetime

我正在尝试根据用户时区触发提醒。用户时区是' America / New_York'

我试图通过以下方式让用户有时间:

now = datetime.now()
now_plus_10 = test_customer.time_zone.localize(now + timedelta(minutes = 10))
now_minus_10 = test_customer.time_zone.localize(now + timedelta(minutes = -10))

提醒时间是13:00。它是从客户对象中收集的,如下所示:

 reminder = customer.reminder #set to 13:00

然后,我想在提醒的10分钟内或之后发送提醒。

我做的比较如下:

if reminder > now_minus_10 and gb_real_time < now_plus_10: 
    reminder_email.send()
else:
    print 'ceiling '+str(now_plus_10)
    print 'not in window don t send'
    print 'floor '+str(now_minus_10)

打印:

ceiling 2014-09-03 10:10:54.547901-04:00  
not in window don t send
floor 2014-09-03 09:50:54.547901-04:00

我在时区:&#39; America / Los_Angeles&#39;其中是上午10点

为什么即使我本地化了now_plus_10和now_minus_10日期,但是它们没有转换为New_York时间,这会使它们像提醒一样13:00并反过来触发提醒?

1 个答案:

答案 0 :(得分:1)

我认为你误解了localize()的作用。 (我假设你在谈论pytz localize(),在这种情况下你可以看到文档here。)

它没有转换次,它需要一个天真的(时区 - 不知道的)日期时间并让它知道(指定它是一个时区)。以下是您的示例中的内容:

now = datetime.now()  # 10:00am local time (no timezone)
later = now + timedelta(minutes=10)  # 10:10am (no timezone)
now_plus_10 = ny_timezone.localize(later)  # 10:10am (NY timezone)

如果你真的想直接在时区之间进行转换,使用pytz,你可以这样做:

now = la_timzeone.localize(datetime.now())  # 10:00am local time (LA timezone)
later = now + timedelta(minutes=10)  # 10:10am (LA timezone)
later_safe = la_timezone.normalize(later)  # because of DST and such
later_ny = later_safe.astimezone(ny_timezone)  # 13:10 (NY timezone)
later_ny_safe = ny_timezone.normalize(later_ny)  # again

现在,这很复杂!这就是为什么pytz和Django都不鼓励您手动本地化和转换时区。你将不得不回顾documentation,但基本上Django的方法是:

  • 所有内部日期时间都是时区感知并使用UTC。
  • 使用django.utils.timezone.now()以UTC格式获取当前时间。
  • 用户输入的日期时间(例如,如果您的用户在表单中输入他或她的提醒时间)会自动识别。要执行此操作,您必须知道用户的时区,然后致电activate()。您也可以使用localtime()手动执行此操作。
  • 使用这些UTC日期时间进行所有比较和算术运算。

我绝对建议以Django的方式做事。