在python中使用datetime获取UTC时间戳 [英] get UTC timestamp in python with datetime

查看:350
本文介绍了在python中使用datetime获取UTC时间戳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法通过指定日期来获取UTC时间戳?我期望的是:

  datetime(2008,1,1,0,0,0,0)

应该导致

  1199145600 

创建一个天真的datetime对象意味着没有时区信息。如果我查看datetime.utcfromtimestamp的文档,则创建一个UTC时间戳表示意味着省去时区信息。所以我猜,创建一个天真的datetime对象(像我这样做)会导致UTC时间戳。但是:

  then = datetime(2008,1,1,0,0,0,0)
datetime。 utcfromtimestamp(float(then.strftime('%s')))

结果

  2007-12-31 23:00:00 

datetime对象中是否还有隐藏的时区信息?我做错了什么?

解决方案

什么是天真的 datetime



默认值 datetime 对象被认为是天真的:它们保留时间信息没有时区信息。考虑天真的 datetime 作为相对数字(即: +4 ),没有明确的起源(实际上你的起源将在整个系统边界是共同的)。考虑将 datetime 作为绝对数字(即: 8 ),具有全世界的共同起源。



没有时区信息,您无法将naivedatetime转换为任何非天真的时间表示( +4 目标,如果我们不知道从哪里开始?)。这就是为什么你不能有一个 datetime.datetime.toutctimestamp()方法。 (cf: http://bugs.python.org/issue1457227



要检查您的 datetime dt 是否天真,请检查 dt .tzinfo ,如果,那么天真:

  datetime.now()## DANGER:返回naïvedatetime指向本地时间
datetime(1970,1,1)##返回naïvedatetime指向用户给定时间

我有天真的datetimes,我该怎么办?



你必须根据你的具体情况做一个假设:
你必须问自己的问题是:你的 datetime 在UTC?或者是当地时间?




  • 如果您使用UTC (您没有麻烦) :

      import calendar 

    def dt2ts(dt):
    转换datetime对象到UTC时间戳

    naive datetime将被视为UTC



    return calendar.timegm(dt.utctimetuple())


  • 如果您没有使用UTC ,欢迎来到地狱。



    在使用前
    函数之前,您必须使 datetime 不天真,



    您需要时区的名称关于
    的信息,如果DST在生成目标天真的日期时间(
    关于DST的最后一个信息需要转角点)时生效

      import pytz ## pip install pytz 

    mytz = pytz.timezone('Europe / Amsterdam') ##设置你的时区

    dt = mytz.normalize(mytz.localize(dt,is_dst = True))##设置is_dst因此

    不提供 is_dst 的后果:



    不使用 is_dst 将生成不正确的时间(和UTC时间戳)
    如果在向后的DST放置到目标datetime时生成
    (例如通过删除一小时来更改DST时间)。



    提供不正确的 is_dst 当然会生成不正确的
    时间(和UTC时间戳)只在DST重叠或孔。而当
    提供
    也是错误的时间时,发生在hole(从未存在的
    转移DST的时间), is_dst 将给出
    的解释如何考虑这个虚假的时间,这是唯一的情况,其中
    .normalize(..)将实际做在这里,因为它将
    将其转换为实际的有效时间(如果需要,更改日期时间和
    DST对象)。请注意,在$ _ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $在
    变量中有虚假的时间,特别是如果您在其他地方重新使用此变量。



    避免使用以下:( cf:使用pytz的日期时区转换

      dt = dt.replace(tzinfo = timezone('Europe / Amsterdam'))## BAD! 

    为什么?因为 .replace()在不考虑目标时间的情况下盲目替换 tzinfo ,而不考虑目标时间,并将选择不好的DST对象
    而$ .localize()使用目标时间和 is_dst 提示
    选择正确的DST对象。




OLD错误的答案(感谢@JFSebastien将其带入):



希望在创建天真的 datetime 对象,因为它与您希望在初始datetime对象创建和要获取UTC时间戳的时刻之间希望不会改变的系统配置相关。这个技巧可以用来给出一个不完美的问题。



使用 time.mktime 我们可以创建一个 utc_mktime

  def utc_mktime(utc_tuple) 
返回历元以来经过的秒数

请注意,不考虑时区。

utc元组必须是:(年,月,日) ,小时,分钟,秒)



如果len(utc_tuple)== 6:
utc_tuple + =(0,0,0)
return time.mktime(utc_tuple) - time.mktime((1970,1,1,0,0,0,0,0,0))

def datetime_to_timestamp(dt):
将datetime对象转换为UTC时间戳

return int(utc_mktime(dt.timetuple()))

您必须确保您的 datetime 对象是在与创建您的 datetime



最后一个解决方案是不正确的,因为它假设现在的UTC偏移量与EPOCH的UTC偏移量相同。对于大量时区(在夏令时(DST)偏移量的一年的特定时刻)不是这样) 。


Is there a way to get the UTC timestamp by specifying the date? What I would expect:

datetime(2008, 1, 1, 0, 0, 0, 0)

should result in

 1199145600

Creating a naive datetime object means that there is no time zone information. If I look at the documentation for datetime.utcfromtimestamp, creating a UTC timestamp means leaving out the time zone information. So I would guess, that creating a naive datetime object (like I did) would result in a UTC timestamp. However:

then = datetime(2008, 1, 1, 0, 0, 0, 0)
datetime.utcfromtimestamp(float(then.strftime('%s')))

results in

2007-12-31 23:00:00

Is there still any hidden time zone information in the datetime object? What am I doing wrong?

解决方案

What is a naïve datetime?

Default datetime objects are said to be "naïve": they keep time information without the time zone information. Think about naïve datetime as a relative number (ie: +4) without a clear origin (in fact your origin will be common throughout your system boundary). Think about aware datetime as absolute numbers (ie: 8) with a common origin for the whole world.

Without timezone information you cannot convert the "naive" datetime towards any non-naive time representation (where does +4 targets if we don't know from where to start ?). This is why you can't have a datetime.datetime.toutctimestamp() method. (cf: http://bugs.python.org/issue1457227)

To check if your datetime dt is naïve, check dt.tzinfo, if None, then it's naïve:

datetime.now()        ## DANGER: returns naïve datetime pointing on local time
datetime(1970, 1, 1)  ## returns naïve datetime pointing on user given time

I have naïve datetimes, what can I do ?

You must make an assumption depending on your particular context: The question you must ask yourself is: was your datetime on UTC ? or was it local time ?

  • If you were using UTC (you are out of trouble):

    import calendar
    
    def dt2ts(dt):
        """Converts a datetime object to UTC timestamp
    
        naive datetime will be considered UTC.
    
        """
    
        return calendar.timegm(dt.utctimetuple())
    

  • If you were NOT using UTC, welcome to hell.

    You have to make your datetime non-naïve prior to using the former function, by giving them back their intended timezone.

    You'll need the name of the timezone and the information about if DST was in effect when producing the target naïve datetime (the last info about DST is required for cornercases):

    import pytz     ## pip install pytz
    
    mytz = pytz.timezone('Europe/Amsterdam')             ## Set your timezone
    
    dt = mytz.normalize(mytz.localize(dt, is_dst=True))  ## Set is_dst accordingly
    

    Consequences of not providing is_dst:

    Not using is_dst will generate incorrect time (and UTC timestamp) if target datetime was produced while a backward DST was put in place (for instance changing DST time by removing one hour).

    Providing incorrect is_dst will of course generate incorrect time (and UTC timestamp) only on DST overlap or holes. And, when providing also incorrect time, occuring in "holes" (time that never existed due to forward shifting DST), is_dst will give an interpretation of how to consider this bogus time, and this is the only case where .normalize(..) will actually do something here, as it'll then translate it as an actual valid time (changing the datetime AND the DST object if required). Note that .normalize() is not required for having a correct UTC timestamp at the end, but is probably recommended if you dislike the idea of having bogus times in your variables, especially if you re-use this variable elsewhere.

    and AVOID USING THE FOLLOWING: (cf: Datetime Timezone conversion using pytz)

    dt = dt.replace(tzinfo=timezone('Europe/Amsterdam'))  ## BAD !!
    

    Why? because .replace() replaces blindly the tzinfo without taking into account the target time and will choose a bad DST object. Whereas .localize() uses the target time and your is_dst hint to select the right DST object.

OLD incorrect answer (thanks @J.F.Sebastien for bringing this up):

Hopefully, it is quite easy to guess the timezone (your local origin) when you create your naive datetime object as it is related to the system configuration that you would hopefully NOT change between the naive datetime object creation and the moment when you want to get the UTC timestamp. This trick can be used to give an imperfect question.

By using time.mktime we can create an utc_mktime:

def utc_mktime(utc_tuple):
    """Returns number of seconds elapsed since epoch

    Note that no timezone are taken into consideration.

    utc tuple must be: (year, month, day, hour, minute, second)

    """

    if len(utc_tuple) == 6:
        utc_tuple += (0, 0, 0)
    return time.mktime(utc_tuple) - time.mktime((1970, 1, 1, 0, 0, 0, 0, 0, 0))

def datetime_to_timestamp(dt):
    """Converts a datetime object to UTC timestamp"""

    return int(utc_mktime(dt.timetuple()))

You must make sure that your datetime object is created on the same timezone than the one that has created your datetime.

This last solution is incorrect because it makes the assumption that the UTC offset from now is the same than the UTC offset from EPOCH. Which is not the case for a lot of timezones (in specific moment of the year for the Daylight Saving Time (DST) offsets).

这篇关于在python中使用datetime获取UTC时间戳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆