将datetime。在Python中,date转换为UTC时间戳

我正在处理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的例子,但是:

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())

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

做的工作。

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

765327 次浏览

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

  • 日期
  • 时间
  • utcoffset [+HHMM or -HHMM]

例如:

__abc0 __abc3 __abc1 __abc3 __abc2

$ 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 timestamp是一个浮点数,在UTC中以秒为单位表示。


编辑:

$ 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

如果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不是同一个时间实例,timestamp1timestamp2可能会不同。

如果d对应于不明确的本地时间(例如,在夏令时转换期间),或者如果d是utc偏移量可能不同的过去(未来)日期,则mktime()可能返回错误的结果。你可以d2。同时,d3。


转换以UTC表示日期的datetime.date对象,不使用calendar.timegm():

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?

将已经以UTC表示时间的datetime.datetime(不是datetime.date)对象转换为相应的POSIX时间戳(float)。

Python 3.3 +

datetime.timestamp():

from datetime import timezone


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

注意:必须显式地提供timezone.utc,否则.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.microseconds + (td.seconds + td.days * 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

如何将一个有意识的datetime对象转换为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()
  • 假设1:您试图将日期转换为时间戳,但是由于日期涵盖了24小时的时间段,因此没有一个时间戳表示该日期。我假设您希望表示该日期在午夜的时间戳(00:00:00.000)。

  • 假设2:您提供的日期与特定的时区不相关,但是您想确定与特定的时区(UTC)的偏移量。如果不知道日期所在的时区,就不可能计算特定时区的时间戳。我假设您希望将日期视为在本地系统时区中。

首先,您可以使用timetuple()成员将日期实例转换为表示各种时间组件的元组:

dtt = d.timetuple() # time.struct_time(tm_year=2011, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=-1)

然后你可以使用time.mktime将其转换为时间戳:

ts = time.mktime(dtt) # 1293868800.0

您可以通过使用epoch时间本身(1970-01-01)测试来验证此方法,在这种情况下,函数应该返回该日期本地时区的时区偏移量:

d = datetime.date(1970,1,1)
dtt = d.timetuple() # time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=-1)
ts = time.mktime(dtt) # 28800.0

28800.0是8小时,这对太平洋时区(我所在的地方)来说是正确的。

这个问题有点混乱。时间戳不是UTC -它们是Unix的东西。日期可能是UTC?假设它是,如果你使用的是Python 3.2+, 简单的日期会让这个问题变得微不足道:

>>> SimpleDate(date(2011,1,1), tz='utc').timestamp
1293840000.0

如果你确实有年、月和日,你不需要创建date:

>>> SimpleDate(2011,1,1, tz='utc').timestamp
1293840000.0

如果日期在其他时区(这很重要,因为我们假设午夜没有相关的时间):

>>> SimpleDate(date(2011,1,1), tz='America/New_York').timestamp
1293858000.0

[simple-date背后的想法是将所有python的日期和时间收集到一个一致的类中,这样你就可以进行任何转换。例如,它也会向另一个方向发展:

>>> SimpleDate(1293858000, tz='utc').date
datetime.date(2011, 1, 1)

遵循python2.7文档,必须使用calendar.timegm()而不是time.mktime()

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

仅限Unix系统:

>>> import datetime
>>> d = datetime.date(2011, 1, 1)
>>> d.strftime("%s")  # <-- THIS IS THE CODE YOU WANT
'1293832800'

注1: dizzyf观察到这个应用本地化的时区。不要在生产中使用。

Jakub narabrbski指出,这个忽略时区信息甚至适用于偏移量感知的datetime(在Python 2.7中测试)。

使用箭头包:

>>> 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)

我定义了自己的两个函数

  • ,已知的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

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

我的观点是:

from datetime import datetime
import time

utc格式的时间戳为:

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

或者,

timestamp = time.time()

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

utcoffset = (datetime.now() - datetime.utcnow()).total_seconds()
timestamp = \
(now - datetime(1970,1,1)).total_seconds() - utcoffset
考虑到你有一个名为ddatetime对象, 使用以下方法获得UTC时间戳:

d.strftime("%Y-%m-%dT%H:%M:%S.%fZ")

而对于相反的方向,使用以下方法:

d = datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%fZ")

这对我来说是可行的,传递一个函数。

from datetime import timezone, datetime, timedelta
import datetime




def utc_converter(dt):
dt = datetime.datetime.now(timezone.utc)
utc_time = dt.replace(tzinfo=timezone.utc)
utc_timestamp = utc_time.timestamp()
return utc_timestamp






# create start and end timestamps
_now = datetime.datetime.now()
str_start = str(utc_converter(_now))
_end = _now + timedelta(seconds=10)
str_end = str(utc_converter(_end))