在Python中将字符串日期转换为时间戳

331

如何将格式为"%d/%m/%Y"的字符串转换为时间戳?

"01/12/2011" -> 1322697600

第二个数字是多少?Unix纪元时间? - Hasteur
5
@Hasteur,是的。第二个数字代表从 Unix 纪元开始到指定日期经过的秒数。这种格式也被称为 POSIX 时间。 - eikonomega
1
时间过得真快啊!你在13点的时候问了这个问题,现在已经是16点了。 - Amir Fo
https://dev59.com/kWgt5IYBdhLWcg3w5hWr - Stefano G.
17个回答

438
>>> import time
>>> import datetime
>>> s = "01/12/2011"
>>> time.mktime(datetime.datetime.strptime(s, "%d/%m/%Y").timetuple())
1322697600.0

12
它假定本地时区中的午夜是2011年1月12日01:00。如果输入是在协调世界时(UTC)中,则可以使用calendar.timegm().toordinal() - jfs
87
datetime.datetime.strptime(s, "%d/%m/%Y").timestamp() 的翻译是:将字符串 s 转换为 datetime 对象,再使用格式化字符串 "%d/%m/%Y" 进行转换,并返回其对应的 Unix 时间戳。 - Tim Diels
23
再次强调,如果没有明确指定时区,.timestamp() 方法假定的是本地时间而不是UTC时间。回答中的代码只有在本地时区的UTC偏移为零的计算机上才能正常运行(产生预期的1322697600)。 - jfs
13
这个不起作用:datetime.datetime.strptime("2014:06:28 11:53:21", "%Y:%m:%d %H:%M:%S").timestamp() 跟踪回溯(最近的调用在最上面): 文件 "<stdin>",第1行,<module> AttributeError: 'datetime.datetime'对象没有'timestamp'属性 - Zdenek Maxa
5
@ZdenekMaxa,datetime.timestamp() 仅适用于 Python 版本大于等于3.3。https://docs.python.org/3/whatsnew/3.3.html - joni jones
显示剩余8条评论

81

我使用ciso8601,它比datetime的strptime快62倍。

t = "01/12/2011"
ts = ciso8601.parse_datetime(t)
# to get time in seconds:
time.mktime(ts.timetuple())

你可以在这里了解更多相关的it技术信息。

6
这是个非常好的建议。我刚刚尝试了一下,成功地节省了大量执行时间。 - David
7
我的天,这太快了。 - Hews
8
加1分,因为您不需要我详细说明时间字符串格式。 - gowenfawr
@gowenfawr 还有datetime.fromisoformat可以正确解析datetime.fromisoformat(str(datetime.now()))。但是,它无法处理JavaScript的new Date().toISOString(),后者也是ISO 8601格式。python-dateutil更擅长猜测,但它可能会猜错区域格式。 - Polv
1
为了使其正常工作,您需要安装 Microsoft Visual C++ 14.0 链接 - Mario Ariyanto

48
>>> int(datetime.datetime.strptime('01/12/2011', '%d/%m/%Y').strftime("%s"))
1322683200

14
Python不支持"%s"这种语法,且该语法不具备可移植性。为了保持原意,我保留了原文中的特殊符号和术语。 - jfs
1
“可读性很重要。”请查看我的使用 dateutil 的答案,以获得更加易读的解决方案。 - törzsmókus
这是答案:https://dev59.com/kWgt5IYBdhLWcg3w5hWr - Stefano G.

47

只需使用 datetime.datetime.strptime

import datetime
stime = "01/12/2011"
print(datetime.datetime.strptime(stime, "%d/%m/%Y").timestamp())

结果:

1322697600

如果要使用UTC而不是本地时区,请使用.replace

datetime.datetime.strptime(stime, "%d/%m/%Y").replace(tzinfo=datetime.timezone.utc).timestamp()

3
完整的回答必须指出它仅适用于 Python 3.3 及以上版本。 - Eduardo
在第一个例子中,结果是float而不是int - Pedro Lobito

45
将字符串转换为日期对象:
from datetime import date, datetime

date_string = "01/12/2011"
date_object = date(*map(int, reversed(date_string.split("/"))))
assert date_object == datetime.strptime(date_string, "%d/%m/%Y").date()

将日期对象转换为 POSIX 时间戳的方式取决于时区。参考在 Python 中将 datetime.date 转换为 UTC 时间戳
  • 日期对象表示UTC时间的午夜

    import calendar
    
    timestamp1 = calendar.timegm(utc_date.timetuple())
    timestamp2 = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * 24*60*60
    assert timestamp1 == timestamp2
    
  • 日期对象表示本地时间的午夜

    import time
    
    timestamp3 = time.mktime(local_date.timetuple())
    assert timestamp3 != timestamp1 or (time.gmtime() == time.localtime())
    

时间戳不同,除非UTC午夜和本地时间相同时刻。


1
@sedeh,帖子中没有wckCalendar。请检查你的代码。 - jfs
@J.F.Sebastian,没错,我并不是试图直接调用wckCalendar。它只是出现在错误信息中。请参见我的帖子这里,讨论这个问题。 - sedeh
@sedeh: 我在你的问题下留了评论(http://stackoverflow.com/questions/25299371/converting-string-date-to-timestamp-in-python-3-4#comment39430758_25299371)。另外,如果输入日期为本地时区(如你代码中的`time.mktime()`所示),则可以使用`.timestamp()`方法来获取Python 3.4中的时间戳。请在帖子中跟随链接 - jfs
1
@törzsmókus:如果答案是错误的,那么它有多易读并不重要。 - jfs
1
@törzsmókus:看我的答案:它可能会产生两个不同的数字。你的答案只产生一个数字,却没有说明是哪一个。 - jfs
显示剩余3条评论

30
答案还取决于您输入日期的时区。如果您的日期是本地日期,那么您可以像katrielalex所说的那样使用mktime() - 只是我不明白他为什么要使用datetime而不是这个更短的版本:
>>> time.mktime(time.strptime('01/12/2011', "%d/%m/%Y"))
1322694000.0

但请注意,我的结果与他的不同,因为我可能处于不同的时区 (而且该结果是无时区的 UNIX 时间戳)

如果输入日期已经是 UTC 时间,那么我认为正确的解决方案是:

>>> calendar.timegm(time.strptime('01/12/2011', '%d/%m/%Y'))
1322697600

1
我认为这样更好。不需要同时导入“time”和“datetime”。 - kennyut
如何处理格式为“YYYY-MM-DD”的日期? - n0obcoder

9

针对初学者(包括我)给出一个答案:

你有一个日期字符串"01/12/2011"。那么它可以使用格式"%d/%m/%Y"进行编写。如果你想要将其格式化为另一种格式,比如"July 9, 2015",请在这里查看一个好的速查表。

  • 导入datetime库。

  • 使用datetime.datetime类来处理日期和时间的组合。

  • 使用strptime方法将一个字符串时间转换为一个对象时间。

  • 最后,使用timestamp方法将Unix纪元时间作为浮点数获取。所以:

import datetime
print( int( datetime.datetime.strptime( "01/12/2011","%d/%m/%Y" ).timestamp() ) )

# prints 1322712000

8
很多答案没有考虑到日期本身是天真的。为了正确,您需要首先将天真的日期转换为带时区的日期时间。
import datetime
import pytz
# naive datetime
d = datetime.datetime.strptime('01/12/2011', '%d/%m/%Y')
>>> datetime.datetime(2011, 12, 1, 0, 0)

# add proper timezone
pst = pytz.timezone('America/Los_Angeles')
d = pst.localize(d)
>>> datetime.datetime(2011, 12, 1, 0, 0,
tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)

# convert to UTC timezone
utc = pytz.UTC
d = d.astimezone(utc)
>>> datetime.datetime(2011, 12, 1, 8, 0, tzinfo=<UTC>)

# epoch is the beginning of time in the UTC timestamp world
epoch = datetime.datetime(1970,1,1,0,0,0,tzinfo=pytz.UTC)
>>> datetime.datetime(1970, 1, 1, 0, 0, tzinfo=<UTC>)

# get the total second difference
ts = (d - epoch).total_seconds()
>>> 1322726400.0

另外:

请注意,在datetime.datetime中使用pytz作为tzinfo时,对于许多时区是不起作用的。请参见datetime with pytz timezone. Different offset depending on how tzinfo is set

# Don't do this:
d = datetime.datetime(2011, 12, 1,0,0,0, tzinfo=pytz.timezone('America/Los_Angeles'))
>>> datetime.datetime(2011, 1, 12, 0, 0, 
tzinfo=<DstTzInfo 'America/Los_Angeles' LMT-1 day, 16:07:00 STD>)
# tzinfo in not PST but LMT here, with a 7min offset !!!

# when converting to UTC:
d = d.astimezone(pytz.UTC)
>>> datetime.datetime(2011, 1, 12, 7, 53, tzinfo=<UTC>)
# you end up with an offset

https://en.wikipedia.org/wiki/Local_mean_time


6

看起来非常高效:

import datetime
day, month, year = '01/12/2011'.split('/')
datetime.datetime(int(year), int(month), int(day)).timestamp()

平均每次循环1.61微秒,标准偏差为120纳秒(7次运行,每次循环100000次)


1
什么是datetime函数?来自datetime库的datetime函数不支持.timestamp() - Joooeey
2
@Joooeey: 在Python 3.3或更高版本中可以使用。虽然在问题发布时还不可用,但自2012年9月以来就已经可用了。 - ShadowRanger

6

我建议使用dateutil

import dateutil.parser
dateutil.parser.parse("01/12/2011", dayfirst=True).timestamp()

这是错误的。OP 期望使用 "%d/%m/%Y" 格式的时间。比较例子:dateutil.parser.parse("01/02/2001")datetime.strptime("01/02/2001", "%d/%m/%Y") - jfs
谢谢@jfs,发现得好。我已经相应地更新了我的答案。 (作为一个非美国人,我不会认为不合逻辑的M/D/Y格式是解析器的默认格式。) - törzsmókus
2
除非您的本地时区是UTC,否则它不会产生预期的1322697600。请参见我2014年的评论。 - jfs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接