django中带有时区的Unix时间戳到日期时间

nkn*_*knj 16 django timezone datetime pytz

我有一个javascript日历,它发送给我一个unixtimestamp.我在新加坡.我希望将此时间戳解释为新加坡时间戳,然后转换为utc以与db进行比较.

我不能,为了我自己的生活,弄清楚如何告诉django这个时间戳是来自新加坡的当前时区.

当我打印时间戳的打印声明时,它会增加8个小时的时间(这意味着django认为我在utc中输入时间并将其本地化为新加坡背景)

在许多其他事情中,我试过: start=datetime.datetime.fromtimestamp(int(start_date)).replace(tzinfo=get_current_timezone())

start_date是1325376000(转换为2012-01-01 00:00:00)

但是,当我打印输出时,我得到2012-01-01 08:00:00 + 06:55.我甚至不知道+06:55来自新加坡的时间是+08:00.我迷失了.

谢谢你的帮助.

settings.py:

TIME_ZONE = 'Asia/Singapore'

USE_TZ = True

Dav*_*ver 22

假设你已经pytz安装:

from datetime import datetime
import pytz
local_tz = pytz.timezone("Asia/Singapore") 
utc_dt = datetime.utcfromtimestamp(timestamp).replace(tzinfo=pytz.utc)
local_dt = local_tz.normalize(utc_dt.astimezone(local_tz))
Run Code Online (Sandbox Code Playgroud)

例如:

>>> from datetime import datetime
>>> import pytz
>>> local_tz = pytz.timezone("Asia/Singapore")
>>> utc_dt = datetime.utcfromtimestamp(1325376000).replace(tzinfo=pytz.utc)
>>> utc_dt
datetime.datetime(2012, 1, 1, 0, 0, tzinfo=<UTC>)
>>> local_dt = local_tz.normalize(utc_dt.astimezone(local_tz))
>>> local_dt
datetime.datetime(2012, 1, 1, 8, 0, tzinfo=<DstTzInfo 'Asia/Singapore' SGT+8:00:00 STD>)
>>> local_dt.replace(tzinfo=None)
datetime.datetime(2012, 1, 1, 8, 0)
Run Code Online (Sandbox Code Playgroud)

  • FFUUU!啊,谢谢!你是对的.我是个白痴.我的答案已经更新,以提供实际,正确的答案. (2认同)

小智 10

以上所有方法都是valide,但不是"django like".这是一个简单的例子,django程序员将如何做到这一点:

from datetime import datetime

from django.utils.timezone import make_aware


# valid timestamp
value = 1531489250 
# you can pass the following obj to a DateTimeField, when your settings.USE_TZ == True
datetime_obj_with_tz = make_aware(datetime.fromtimestamp(value))
Run Code Online (Sandbox Code Playgroud)

Django github timezone模块上查看更多utilites 以获得全部概述......

  • 注意:此解决方案通过朴素的本地时间引入了不必要的转换(如果未传递“tz”参数,则由“fromtimestamp()”返回),这可能会以各种方式失败,例如,在“fromtimestamp()”无法访问的系统上tz 数据库或模糊的当地时间。[明确传递 tz 参数,如我的答案所示](/sf/answers/2251470721/),在这种情况下,您不需要调用 `make_aware()` (将 `tz` 传递给 ` fromtimestamp()` 导致 `tz.fromutc()` 调用比 `make_aware()` 调用的 `tz.localize()` 更健壮。 (3认同)

jfs*_*jfs 6

将pytz tzinfo对象传递给fromtimestamp()方法:

#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz

tz = pytz.timezone("Asia/Singapore")
print(datetime.fromtimestamp(1325376000, tz))
# -> 2012-01-01 08:00:00+08:00
Run Code Online (Sandbox Code Playgroud)

注意:结果对象是时区感知的:您可以将其与其他有意识的日期时间对象进行比较,即,您无需将其转换为UTC进行比较 - 您可以按原样使用它.

我甚至不知道+06:55来自新加坡的时间是+08:00.

你看到+06:55由于无效的.replace()通话.get_current_timezone()返回pytz.timezone("Asia/Singapore")具有变量utc offset(在不同日期可能有不同的utc偏移量).当你调用.replace()一些随机(取决于实现)时使用tzinfo对象.问题是该.replace()方法不允许pytz.timezone("Asia/Singapore")为输入日期选择正确的tzinfo.

>>> list(tz._tzinfos.values())
[<DstTzInfo 'Asia/Singapore' MALT+7:00:00 STD>,
 <DstTzInfo 'Asia/Singapore' MALT+7:20:00 STD>,
 <DstTzInfo 'Asia/Singapore' JST+9:00:00 STD>,
 <DstTzInfo 'Asia/Singapore' SMT+6:55:00 STD>,
 <DstTzInfo 'Asia/Singapore' SGT+7:30:00 STD>,
 <DstTzInfo 'Asia/Singapore' MALT+7:30:00 STD>,
 <DstTzInfo 'Asia/Singapore' MALST+7:20:00 DST>,
 <DstTzInfo 'Asia/Singapore' LMT+6:55:00 STD>,
 <DstTzInfo 'Asia/Singapore' SGT+8:00:00 STD>]
Run Code Online (Sandbox Code Playgroud)

也就是说,无论是+06:55+0800是新加坡有效(在不同的日期).这就是为什么你应该.replace()只使用具有常量utc偏移的时区,例如utc时区本身(偏移量为零,总是对于任何日期).

fromtimestamp(,tz)tz.fromutc()内部方法调用允许tz为给定的utc时间选择正确的偏移量.