我正在处理Python中的日期,我需要将它们转换为UTC时间戳以供使用 在Javascript。下面的代码不能工作:

>>> d = datetime.date(2011,01,01)
>>> datetime.datetime.utcfromtimestamp(time.mktime(d.timetuple()))
datetime.datetime(2010, 12, 31, 23, 0)

首先将date对象转换为datetime也没有帮助。我在这个链接中尝试了这个例子,但是:

from pytz import utc, timezone
from datetime import datetime
from time import mktime
input_date = datetime(year=2011, month=1, day=15)

现在:

mktime(utc.localize(input_date).utctimetuple())

or

mktime(timezone('US/Eastern').localize(input_date).utctimetuple())

做的工作。

一般问题:如何根据UTC将日期转换为从epoch开始的秒数?


当前回答

使用箭头包:

>>> import arrow
>>> arrow.get(2010, 12, 31).timestamp
1293753600
>>> time.gmtime(1293753600)
time.struct_time(tm_year=2010, tm_mon=12, tm_mday=31, 
    tm_hour=0, tm_min=0, tm_sec=0, 
    tm_wday=4, tm_yday=365, tm_isdst=0)

其他回答

使用箭头包:

>>> import arrow
>>> arrow.get(2010, 12, 31).timestamp
1293753600
>>> time.gmtime(1293753600)
time.struct_time(tm_year=2010, tm_mon=12, tm_mday=31, 
    tm_hour=0, tm_min=0, tm_sec=0, 
    tm_wday=4, tm_yday=365, tm_isdst=0)

一个完整的时间字符串包含:

日期 时间 utcoffset [+HHMM或-HHMM]

例如:

0000 == UNIX时间戳:3600

$ python3
>>> from datetime import datetime
>>> from calendar import timegm
>>> tm = '1970-01-01 06:00:00 +0500'
>>> fmt = '%Y-%m-%d %H:%M:%S %z'
>>> timegm(datetime.strptime(tm, fmt).utctimetuple())
3600

注意:

UNIX时间戳是一个浮点数,以UTC标准从epoch开始的秒数表示。


编辑:

$ python3
>>> from datetime import datetime, timezone, timedelta
>>> from calendar import timegm
>>> dt = datetime(1970, 1, 1, 6, 0)
>>> tz = timezone(timedelta(hours=5))
>>> timegm(dt.replace(tzinfo=tz).utctimetuple())
3600

我定义了自己的两个函数

,已知的utc_time2datetime (utc_time表示tz =没有) datetime2utc_time (datetime)

在这里:

import time
import datetime
from pytz import timezone
import calendar
import pytz


def utc_time2datetime(utc_time, tz=None):
    # convert utc time to utc datetime
    utc_datetime = datetime.datetime.fromtimestamp(utc_time)

    # add time zone to utc datetime
    if tz is None:
        tz_datetime = utc_datetime.astimezone(timezone('utc'))
    else:
        tz_datetime = utc_datetime.astimezone(tz)

    return tz_datetime


def datetime2utc_time(datetime):
    # add utc time zone if no time zone is set
    if datetime.tzinfo is None:
        datetime = datetime.replace(tzinfo=timezone('utc'))

    # convert to utc time zone from whatever time zone the datetime is set to
    utc_datetime = datetime.astimezone(timezone('utc')).replace(tzinfo=None)

    # create a time tuple from datetime
    utc_timetuple = utc_datetime.timetuple()

    # create a time element from the tuple an add microseconds
    utc_time = calendar.timegm(utc_timetuple) + datetime.microsecond / 1E6

    return utc_time

如果d = date(2011, 1,1)是UTC:

>>> from datetime import datetime, date
>>> import calendar
>>> timestamp1 = calendar.timegm(d.timetuple())
>>> datetime.utcfromtimestamp(timestamp1)
datetime.datetime(2011, 1, 1, 0, 0)

如果d在本地时区:

>>> import time
>>> timestamp2 = time.mktime(d.timetuple()) # DO NOT USE IT WITH UTC DATE
>>> datetime.fromtimestamp(timestamp2)
datetime.datetime(2011, 1, 1, 0, 0)

如果本地时区的midnight与UTC的midnight不是同一个时间实例,则timestamp1和timestamp2可能不同。

mktime()可能会返回一个错误的结果,如果d对应于一个不明确的本地时间(例如,在DST转换期间),或者如果d是一个过去(未来)日期,此时utc偏移量可能已经不同,并且C mktime()无法访问给定平台上的tz数据库。你可以使用pytz模块(例如,通过tzlocal.get_localzone())来访问所有平台上的tz数据库。此外,如果使用了“正确的”时区,utcfromtimestamp()可能会失败,mktime()可能会返回非posix时间戳。


转换datetime。date对象,以UTC表示日期,不包含日历。

DAY = 24*60*60 # POSIX day in seconds (exact value)
timestamp = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * DAY
timestamp = (utc_date - date(1970, 1, 1)).days * DAY

我怎么能得到一个日期转换为秒自纪元根据UTC?

转换datetime。datetime(不是datetime.date)对象,该对象已经表示了对应POSIX时间戳(浮点数)的UTC时间。

Python 3.3 +

datetime。timestamp ():

from datetime import timezone

timestamp = dt.replace(tzinfo=timezone.utc).timestamp()

注:必须提供时区。否则.timestamp()假定你的天真datetime对象在本地时区。

Python 3 (< 3.3)

来自datetime.utcfromtimestamp()的文档:

没有从datetime实例获取时间戳的方法, 但是POSIX时间戳对应的datetime实例dt可以 简单计算如下。对于naive dt:

timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)

对于一个敏感的dt:

timestamp = (dt - datetime(1970,1,1, tzinfo=timezone.utc)) / timedelta(seconds=1)

有趣的阅读:大纪元时间和一天中的时间之间的区别是什么时间?和已经过去了多少秒?

参见:datetime需要一个“epoch”方法

Python 2

将上述代码改编为Python 2:

timestamp = (dt - datetime(1970, 1, 1)).total_seconds()

其中timedelta.total_seconds()等价于(td. total_seconds)。微秒+ (td。秒+ td。天* 24 * 3600)* 10**6)/启用真除法计算的10**6。

例子

from __future__ import division
from datetime import datetime, timedelta

def totimestamp(dt, epoch=datetime(1970,1,1)):
    td = dt - epoch
    # return td.total_seconds()
    return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) / 10**6 

now = datetime.utcnow()
print now
print totimestamp(now)

小心浮点问题。

输出

2012-01-08 15:34:10.022403
1326036850.02

如何将一个感知日期时间对象转换为POSIX时间戳

assert dt.tzinfo is not None and dt.utcoffset() is not None
timestamp = dt.timestamp() # Python 3.3+

Python 3:

from datetime import datetime, timedelta, timezone

epoch = datetime(1970, 1, 1, tzinfo=timezone.utc)
timestamp = (dt - epoch) / timedelta(seconds=1)
integer_timestamp = (dt - epoch) // timedelta(seconds=1)

Python 2:

# utc time = local time              - utc offset
utc_naive  = dt.replace(tzinfo=None) - dt.utcoffset()
timestamp = (utc_naive - datetime(1970, 1, 1)).total_seconds()

这次深入的讨论给我留下了深刻的印象。

我的观点是:

from datetime import datetime
import time

utc格式的时间戳为:

timestamp = \
    (datetime.utcnow() - datetime(1970,1,1)).total_seconds()

or,

timestamp = time.time()

if now的结果是datetime.now(),在相同的DST

utcoffset = (datetime.now() - datetime.utcnow()).total_seconds()
timestamp = \
    (now - datetime(1970,1,1)).total_seconds() - utcoffset