将datetime转换为Unix时间戳,并在python中将其转换回

将datetime转换为Unix时间戳,并在python中将其转换回,python,datetime,timestamp,Python,Datetime,Timestamp,我有dt=datetime(2013,9,1,11),我想得到这个datetime对象的Unix时间戳 当我做(dt-datetime(1970,1,1)).total_seconds()时,我得到了时间戳1378033200 使用datetime.fromtimestamp将其转换回时,我得到了datetime.datetime(2013,9,1,6,0) 时间不匹配。我错过了什么?你错过的是时区 假设您离UTC还有五个小时,因此2013-09-01T11:00:00本地时间和2013-09-

我有
dt=datetime(2013,9,1,11)
,我想得到这个datetime对象的Unix时间戳

当我做
(dt-datetime(1970,1,1)).total_seconds()
时,我得到了时间戳
1378033200

使用
datetime.fromtimestamp
将其转换回时,我得到了
datetime.datetime(2013,9,1,6,0)


时间不匹配。我错过了什么?你错过的是时区

假设您离UTC还有五个小时,因此2013-09-01T11:00:00本地时间和2013-09-01T06:00:00Z时间是相同的

您需要阅读文档的顶部,其中解释了时区和“天真”和“感知”对象

如果原始原始日期时间是UTC,则恢复它的方法是使用而不是使用
fromtimestamp

另一方面,如果原始的naive datetime是本地的,那么首先就不应该从中减去UTC时间戳;改用
datetime.fromtimestamp(0)

或者,如果您有aware datetime对象,则需要在两侧使用本地(aware)历元,或者显式地与UTC进行转换

如果您已经拥有或可以升级到Python3.3或更高版本,那么您可以通过使用该方法而不是试图自己解决如何解决这些问题来避免所有这些问题。即使你没有,你也可以考虑。


(如果您可以等待Python3.4的发布,它看起来很可能会进入最终版本,这意味着J.F.Sebastian和我在评论中提到的所有东西都应该只使用stdlib就可以实现,并且在Unix和Windows上都可以以同样的方式工作。)而不是使用此表达式从
dt
创建POSIX时间戳

(dt - datetime(1970,1,1)).total_seconds()
使用以下命令:

int(dt.strftime("%s"))
在你的例子中,我使用第二种方法得到了正确的答案

编辑:一些后续。。。经过一些评论(见下文),我对
strftime
中缺少对
%s
的支持或文档感到好奇。以下是我的发现:

在for
datetime
time
中,字符串
STRFTIME\u FORMAT\u code
告诉我们:

"Other codes may be available on your platform.
 See documentation for the C library strftime function."
因此,现在如果我们
manstrftime
(在诸如Mac OS X之类的BSD系统上),您将发现对
%s
的支持:

"%s is replaced by the number of seconds since the Epoch, UTC (see mktime(3))."

无论如何,这就是为什么
%s
可以在它所做的系统上工作。但有更好的办法解决OP的问题(考虑时区)。请参见@abarnert在此处接受的答案。

好吧,在转换为unix时间戳时,python基本上采用UTC,但在转换回UTC时,它将为您提供一个转换为本地时区的日期

看这个问题/答案;
解决方案是


如果要将python datetime转换为纪元后的秒数,则应显式执行此操作:

>>> import datetime
>>> datetime.datetime(2012, 04, 01, 0, 0).strftime('%s')
'1333234800'
>>> (datetime.datetime(2012, 04, 01, 0, 0) - datetime.datetime(1970, 1, 1)).total_seconds()
1333238400.0
在Python 3.3+中,您可以改为使用:


您错过了时区信息(已回答,同意)

软件包允许使用datetimes避免这种折磨;它已经被编写、测试、pypi发布、跨python(2.6-3.xx)

您所需的一切:
pip安装箭头
(或添加到依赖项)

你的案子的解决方案
dt=datetime(2013,9,1,11)
arrow.get(dt).timestamp
# >>> 1378033200
bc=arrow.get(1378033200).datetime
印刷品(bc)
#>>>datetime.datetime(2013,9,1,11,0,tzinfo=tzutc())
打印(bc.isoformat())
#>>>'2013-09-01T11:00:00+00:00'

如果datetime对象表示UTC时间,请不要使用time.mktime,因为它假定元组位于本地时区。相反,请使用calendar.timegm:

>>> import datetime, calendar
>>> d = datetime.datetime(1970, 1, 1, 0, 1, 0)
>>> calendar.timegm(d.timetuple())
60

如果您想要UTC时间戳:
time.mktime
仅用于localdt。使用
calendar.timegm
是安全的,但dt必须使用UTC区域,因此将区域更改为UTC。如果在UTC中使用dt,只需使用
calendar.timegm

来处理UTC时区:

time_stamp = calendar.timegm(dt.timetuple())

datetime.utcfromtimestamp(time_stamp)

这个类将满足您的需要,您可以将变量传递到ConvertUnixToDatetime&调用您希望它基于哪个函数进行操作

from datetime import datetime
import time

class ConvertUnixToDatetime:
    def __init__(self, date):
        self.date = date

    # Convert unix to date object
    def convert_unix(self):
        unix = self.date

        # Check if unix is a string or int & proceeds with correct conversion
        if type(unix).__name__ == 'str':
            unix = int(unix[0:10])
        else:
            unix = int(str(unix)[0:10])

        date = datetime.utcfromtimestamp(unix).strftime('%Y-%m-%d %H:%M:%S')

        return date

    # Convert date to unix object
    def convert_date(self):
        date = self.date

        # Check if datetime object or raise ValueError
        if type(date).__name__ == 'datetime':
            unixtime = int(time.mktime(date.timetuple()))
        else:
            raise ValueError('You are trying to pass a None Datetime object')
        return type(unixtime).__name__, unixtime


if __name__ == '__main__':

    # Test Date
    date_test = ConvertUnixToDatetime(datetime.today())
    date_test = date_test.convert_date()
    print(date_test)

    # Test Unix
    unix_test = ConvertUnixToDatetime(date_test[1])
    print(unix_test.convert_unix())

相关:作为旁注,如果您使用的是Python3.3+,那么您真的非常想使用该方法,而不是自己尝试。首先,这完全避免了从不同时区中减去原始时间的可能性。
dt
来自哪里?这是当地时间还是UTC时间?@abarnert我还想提交一个清除所有代码页和unicode符号的请求,也就是说,禁止所有非ascii和非默认代码页语言。仍然允许绘制符号。@DanielF:请求被拒绝。我对在这里创造一种单一世界的语言不感兴趣,即使我们这样做了,我也不想让历史语言学家和托尔金学者的生活变得不可能。Unicode已经解决了这个问题,除了某些组织和产品(TRON consortium、使用Shift JIS而不是UTF-8的日本软件、微软仍在提供用户文本文件默认为cp1252的操作系统,以及假装UTF-16是固定宽度字符集和/或与Unicode相同的各种SDK)如果
dt
在本地时区,则问题中的公式不正确
datetime。应使用fromtimestamp(0)
(当前时区中的历元)而不是
datetime(1970,1,1)
(UTC中的unix历元)@J.F.Sebastian:我不想详细介绍这三种可能性,但我想你是对的,我应该这样做。顺便说一句,如果系统没有存储历史时区信息,例如在Windows上,fromtimestamp(0)可能会失败
pytz
可以用在这种情况下。@J.F.Sebastian:但是
pytz
没有帮助,除非你已经知道你在哪个时区;要以编程方式实现这一点,您需要一个不同的库来获取当前Windows时区,并将其转换为
pytz
时区和/或按名称查找它。还有一个
tzlocal
模块也适用于Windows。这是你能做到的
def dt2ts(dt, utc=False):
    if utc:
        return calendar.timegm(dt.timetuple())
    if dt.tzinfo is None:
        return int(time.mktime(dt.timetuple()))
    utc_dt = dt.astimezone(tz.tzutc()).timetuple()
    return calendar.timegm(utc_dt)
time_stamp = calendar.timegm(dt.timetuple())

datetime.utcfromtimestamp(time_stamp)
def datetime_to_epoch(d1):

    # create 1,1,1970 in same timezone as d1
    d2 = datetime(1970, 1, 1, tzinfo=d1.tzinfo)
    time_delta = d1 - d2
    ts = int(time_delta.total_seconds())
    return ts


def epoch_to_datetime_string(ts, tz_name="UTC"):
    x_timezone = timezone(tz_name)
    d1 = datetime.fromtimestamp(ts, x_timezone)
    x = d1.strftime("%d %B %Y %H:%M:%S")
    return x
from datetime import datetime
import time

class ConvertUnixToDatetime:
    def __init__(self, date):
        self.date = date

    # Convert unix to date object
    def convert_unix(self):
        unix = self.date

        # Check if unix is a string or int & proceeds with correct conversion
        if type(unix).__name__ == 'str':
            unix = int(unix[0:10])
        else:
            unix = int(str(unix)[0:10])

        date = datetime.utcfromtimestamp(unix).strftime('%Y-%m-%d %H:%M:%S')

        return date

    # Convert date to unix object
    def convert_date(self):
        date = self.date

        # Check if datetime object or raise ValueError
        if type(date).__name__ == 'datetime':
            unixtime = int(time.mktime(date.timetuple()))
        else:
            raise ValueError('You are trying to pass a None Datetime object')
        return type(unixtime).__name__, unixtime


if __name__ == '__main__':

    # Test Date
    date_test = ConvertUnixToDatetime(datetime.today())
    date_test = date_test.convert_date()
    print(date_test)

    # Test Unix
    unix_test = ConvertUnixToDatetime(date_test[1])
    print(unix_test.convert_unix())