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

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

"01/12/2011" -> 1322697600
703503 次浏览
>>> int(datetime.datetime.strptime('01/12/2011', '%d/%m/%Y').strftime("%s"))
1322683200
>>> import time
>>> import datetime
>>> s = "01/12/2011"
>>> time.mktime(datetime.datetime.strptime(s, "%d/%m/%Y").timetuple())
1322697600.0

首先,必须strptime类将字符串转换为struct_time格式。

然后使用mktime从那里获得你的浮点数。

答案也取决于你输入的日期和时区。如果你的日期是本地日期,那么你可以像katrielalex说的那样使用mktime() -只是我不明白为什么他使用datetime而不是这个更短的版本:

>>> time.mktime(time.strptime('01/12/2011', "%d/%m/%Y"))
1322694000.0

但是请注意,我的结果与他的结果不同,因为我可能在不同的TZ中(结果是无时区的UNIX时间戳)

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

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

将字符串转换为日期对象:

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

将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
    
  • date object represents midnight in local time

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

The timestamps are different unless midnight in UTC and in local time is the same time instance.

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

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

你可以学到更多在这里

我建议dateutil:

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

只使用datetime。时间戳(您的datetime实例),datetime实例包含时区信息,因此时间戳将是标准utc时间戳。如果您将datetime转换为timetuple,它将失去它的时区,因此结果将是错误的。 如果你想提供一个接口,你应该这样写: Int (datetime.timestamp(time_instance)) * 1000

很多答案都没有考虑到日期一开始就很天真

为了正确,您需要首先将初始日期设置为具有时区意识的datetime

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中对tzinfo使用pytz并不适用于许多时区。看到带pytz时区的日期时间。不同的偏移量取决于tzinfo的设置方式

# 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

似乎相当有效:

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

1.61µs±120 ns /循环(7次运行的平均值±标准值,每次100000次循环)

简单地使用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()

你可以参考下面的链接,使用datetime.datetime中的strptime函数,从任何格式和时区转换日期。

https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior

一个获取UNIX纪元时间的简单函数。

请注意:此函数假定输入日期时间为UTC格式(此处参考评论)。

def utctimestamp(ts: str, DATETIME_FORMAT: str = "%d/%m/%Y"):
import datetime, calendar
ts = datetime.datetime.utcnow() if ts is None else datetime.datetime.strptime(ts, DATETIME_FORMAT)
return calendar.timegm(ts.utctimetuple())

使用:

>>> utctimestamp("01/12/2011")
1322697600
>>> utctimestamp("2011-12-01", "%Y-%m-%d")
1322697600

你可以转换成等值格式

my_date = '2020/08/08'
my_date = my_date.replace('/','-') # just to adapte to your question
date_timestamp = datetime.datetime.fromisoformat(my_date).timestamp()

我想给初学者(像我一样)一个答案:

你有日期字符串"01/12/2011"。然后它可以用格式"%d/%m/%Y"来写。如果你想格式化为另一种格式,如"July 9, 2015"在这里是一个很好的备忘单。

  • 导入datetime库。

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

  • 使用strptime方法将字符串datetime转换为对象datetime。

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

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


# prints 1322712000

你可以去两个方向unix epoch <==> datetime :

import datetime
import time




the_date = datetime.datetime.fromtimestamp( 1639763585 )






unix_time = time.mktime(the_date.timetuple())


assert  ( the_date == datetime.datetime.fromtimestamp(unix_time) ) & \
( time.mktime(the_date.timetuple()) == unix_time         )