Python:用微秒将字符串转换为时间戳
我想将字符串日期格式转换为微秒时间戳 我尝试了以下方法,但没有给出预期结果:Python:用微秒将字符串转换为时间戳,python,datetime,timestamp,converter,Python,Datetime,Timestamp,Converter,我想将字符串日期格式转换为微秒时间戳 我尝试了以下方法,但没有给出预期结果: """input string date -> 2014-08-01 04:41:52,117 expected result -> 1410748201.117""" import time import datetime myDate = "2014-08-01 04:41:52,117" timestamp = time.mktime(datetime.datetime.strptime(myDa
"""input string date -> 2014-08-01 04:41:52,117
expected result -> 1410748201.117"""
import time
import datetime
myDate = "2014-08-01 04:41:52,117"
timestamp = time.mktime(datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f").timetuple())
print timestamp
> 1410748201.0
毫秒到哪里去了?时间元组中的微秒组件没有插槽:
>>> import time
>>> import datetime
>>> myDate = "2014-08-01 04:41:52,117"
>>> datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f").timetuple()
time.struct_time(tm_year=2014, tm_mon=8, tm_mday=1, tm_hour=4, tm_min=41, tm_sec=52, tm_wday=4, tm_yday=213, tm_isdst=-1)
您必须手动添加这些内容:
>>> dt = datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f")
>>> time.mktime(dt.timetuple()) + (dt.microsecond / 1000000.0)
1406864512.117
您可以遵循的另一种方法是生成一个相对于历元的时间戳,然后使用以下命令获取时间戳:
使用本地时间纪元是经过深思熟虑的,因为您有一个简单的(不知道时区的)日期时间值。但是,根据本地时区的历史记录,此方法可能不准确,请参阅。您必须先使用本地时区将原始datetime值转换为时区感知的datetime值,然后再减去时区感知的历元
因此,更容易坚持使用timetuple()
+微秒的方法
演示:
毫秒到哪里去了
这是最简单的部分.timetuple()
调用会删除它们。您可以使用.microsecond
属性将它们添加回。对于朴素的datetime对象,该函数就是这样工作的:
def timestamp(self):
"Return POSIX timestamp as float"
if self._tzinfo is None:
return _time.mktime((self.year, self.month, self.day,
self.hour, self.minute, self.second,
-1, -1, -1)) + self.microsecond / 1e6
else:
return (self - _EPOCH).total_seconds()
如果可能的话,在您的案例中可以忽略约1小时的错误就足够了。我假设您需要微秒,因此您不能默默地忽略~1小时的时间错误
一般来说,将以字符串形式给出的本地时间正确转换为POSIX时间戳是一项复杂的任务。您可以将本地时间转换为UTC,然后再转换
有两个主要问题:
- 本地时间可能不存在或不明确,例如,在DST转换期间,同一时间可能出现两次
- 本地时区的UTC偏移量在过去可能不同,因此是一个简单的:
pytz
Python中的模块)解决这两个问题:
结果是timestamp
——一个timedelta
对象,您可以将其转换为秒、毫秒等
此外,在闰秒前后/闰秒期间,不同的系统可能表现不同。大多数应用程序可以忽略它们的存在
一般来说,除了本地时间之外,存储POSIX时间戳可能更简单,而不是试图从本地时间猜测它。在Python 3.4及更高版本中,您可以使用
timestamp = datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f").timestamp()
这不需要导入时间
模块。它还使用较少的步骤,因此应该更快。对于较早版本的python,提供的其他答案可能是您的最佳选择
但是,生成的时间戳将以本地时间而不是UTC来解释myDate,如果myDate以UTC给出,则可能会导致问题。如果输入日期(2014-08-01)与时间戳(2014-09-15 02:30:01.117Z)不对应,则输入日期(2014-09-15 02:30:01.117Z)1
(dt-epoch)
不正确,如果dt
是原始本地时间。当地时间可能会推迟(北半球秋季的DST转换)。在这种情况下不应设置时间戳。2“当地时间纪元”也可能会产生误导。epoch是一个单一的时间实例(对于Python来说是1970年)——世界各地都是一样的。如果C库支持历史时区数据库或本地时区的UTC在该时间具有相同的值,则datetime.fromtimstamp(0)
返回与历元对应的本地时间。@J.F.Sebastian:epoch
值使用fromtimstamp()
,而不是utcfromtimestamp()
,要处理DST差异,正是因为dt
值太天真了。@J.F.Sebastian:如果我使用utcfromtimestamp()
,我必须首先使dt
时区感知,从而允许Python补偿DST问题。你误解了。问题是公式使用的是当地时间。当地时间可能模棱两可(如果它是输入,并且没有其他可用信息,您将无能为力)。而且本地时区的utc偏移量在过去可能不同(您需要tz数据库来找到它)。正确的公式:ts=utc\u time-epoch\u in\u utc=local time-utc offset(现在)-local time中的epoch+utc offset(那时)
。您的公式相当于使用UTC偏移量,即假定UTC偏移量(现在)=UTC偏移量(当时)
@J.F.Sebastian:啊,这一点很好。如果有一个合适的时区数据库,这个公式会更简单。作为一种近似,忽略历史问题,它足够好吗?因为time.time()
也不使用历史值。注意:datetime.timestamp
仅在Python 3中可用;OP使用的是Python 2(从print
语句判断)。@MartijnPieters:我没有建议使用.timestamp()
方法。我只是用它作为一个例子(有缺陷的)实现。我不是有意建议你这么做。我只是指出Python2中不存在该方法。@MartijnPieters:我理解你所说的。我不明白你为什么这么说。在这种情况下,代码恰好包含在Python3 stdlib+d中并不重要。微秒/1e6
在Python2和Python3上的工作方式相同。
def timestamp(self):
"Return POSIX timestamp as float"
if self._tzinfo is None:
return _time.mktime((self.year, self.month, self.day,
self.hour, self.minute, self.second,
-1, -1, -1)) + self.microsecond / 1e6
else:
return (self - _EPOCH).total_seconds()
from datetime import datetime
import pytz # $ pip install pytz
from tzlocal import get_localzone # $ pip install tzlocal
tz = get_localzone() # get pytz timezone corresponding to the local timezone
naive_d = datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f")
# a) raise exception for non-existent or ambiguous times
d = tz.localize(naive_d, is_dst=None)
## b) assume standard time, adjust non-existent times
#d = tz.normalize(tz.localize(naive_d, is_dst=False))
## c) assume DST is in effect, adjust non-existent times
#d = tz.normalize(tz.localize(naive_d, is_dst=True))
timestamp = d - datetime(1970, 1, 1, tzinfo=pytz.utc)
timestamp = datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f").timestamp()