提问人:Jurudocs 提问时间:9/29/2011 最后编辑:Mateen UlhaqJurudocs 更新时间:11/22/2023 访问量:792695
将日期时间格式化为包含毫秒的字符串
Format a datetime into a string with milliseconds
答:
使用 strftime
:
>>> from datetime import datetime
>>> datetime.utcnow().strftime('%Y%m%d%H%M%S%f')
'20220402055654344968'
评论
[:-3]
我假设您的意思是您正在寻找比 datetime.datetime.strftime() 更快的东西,并且本质上是从 utc 时间戳中剥离非 alpha 字符。
你的方法稍微快一点,我认为你可以通过切弦来加快速度:
>>> import timeit
>>> t=timeit.Timer('datetime.utcnow().strftime("%Y%m%d%H%M%S%f")','''
... from datetime import datetime''')
>>> t.timeit(number=10000000)
116.15451288223267
>>> def replaceutc(s):
... return s\
... .replace('-','') \
... .replace(':','') \
... .replace('.','') \
... .replace(' ','') \
... .strip()
...
>>> t=timeit.Timer('replaceutc(str(datetime.datetime.utcnow()))','''
... from __main__ import replaceutc
... import datetime''')
>>> t.timeit(number=10000000)
77.96774983406067
>>> def sliceutc(s):
... return s[:4] + s[5:7] + s[8:10] + s[11:13] + s[14:16] + s[17:19] + s[20:]
...
>>> t=timeit.Timer('sliceutc(str(datetime.utcnow()))','''
... from __main__ import sliceutc
... from datetime import datetime''')
>>> t.timeit(number=10000000)
62.378515005111694
评论
from datetime import datetime
from time import clock
t = datetime.utcnow()
print 't == %s %s\n\n' % (t,type(t))
n = 100000
te = clock()
for i in xrange(1):
t_stripped = t.strftime('%Y%m%d%H%M%S%f')
print clock()-te
print t_stripped," t.strftime('%Y%m%d%H%M%S%f')"
print
te = clock()
for i in xrange(1):
t_stripped = str(t).replace('-','').replace(':','').replace('.','').replace(' ','')
print clock()-te
print t_stripped," str(t).replace('-','').replace(':','').replace('.','').replace(' ','')"
print
te = clock()
for i in xrange(n):
t_stripped = str(t).translate(None,' -:.')
print clock()-te
print t_stripped," str(t).translate(None,' -:.')"
print
te = clock()
for i in xrange(n):
s = str(t)
t_stripped = s[:4] + s[5:7] + s[8:10] + s[11:13] + s[14:16] + s[17:19] + s[20:]
print clock()-te
print t_stripped," s[:4] + s[5:7] + s[8:10] + s[11:13] + s[14:16] + s[17:19] + s[20:] "
结果
t == 2011-09-28 21:31:45.562000 <type 'datetime.datetime'>
3.33410112179
20110928212155046000 t.strftime('%Y%m%d%H%M%S%f')
1.17067364707
20110928212130453000 str(t).replace('-','').replace(':','').replace('.','').replace(' ','')
0.658806915404
20110928212130453000 str(t).translate(None,' -:.')
0.645189262881
20110928212130453000 s[:4] + s[5:7] + s[8:10] + s[11:13] + s[14:16] + s[17:19] + s[20:]
使用 translate() 和切片方法同时
运行 translate() 具有在一行中可用的优势
在第一个的基础上比较时间:
1.000 * t.strftime('%Y%m%d%H%M%S%f')
0.351 * str(t).replace('-','').replace(':','').replace('.','').replace(' ','')
0.198 * str(t).translate(None,' -:.')
0.194 * 秒[:4] + 秒[5:7] + 秒[8:10] + 秒[11:13] + 秒[14:16] + 秒[17:19] + s[20:]
评论
若要获取具有毫秒的日期字符串,请使用修剪(微秒)的最后三位数字:[:-3]
%f
>>> from datetime import datetime
>>> datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
'2022-09-24 10:18:32.926'
或更短:
>>> from datetime import datetime
>>> datetime.utcnow().strftime('%F %T.%f')[:-3]
'2022-09-24 10:18:32.926'
有关更多 “” 格式代码,请参见 Python 文档,完整列表请参见 strftime(3)
手册页。%
评论
import datetime
from datetime import datetime
datetime.datetime.utcnow().strftime("%H:%M:%S.%f")
用于删除最后 3 个字符,因为是微秒:[:-3]
%f
>>> from datetime import datetime
>>> datetime.now().strftime('%Y/%m/%d %H:%M:%S.%f')[:-3]
'2013/12/04 16:50:03.141'
评论
我处理了同样的问题,但在我的情况下,毫秒是四舍五入而不是截断很重要
from datetime import datetime, timedelta
def strftime_ms(datetime_obj):
y,m,d,H,M,S = datetime_obj.timetuple()[:6]
ms = timedelta(microseconds = round(datetime_obj.microsecond/1000.0)*1000)
ms_date = datetime(y,m,d,H,M,S) + ms
return ms_date.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
@Cabbi提出了一个问题,即在某些系统(带有 Python 2.7 的 Windows)上,微秒格式可能会错误地给出“0”
,因此简单地修剪最后三个字符是不可移植的。此类系统不遵循文档中指定的行为:%f
命令 | 意义 | 例 |
---|---|---|
%f | 微秒作为十进制数,零填充为 6 位数字。 | 000000, 000001, ..., 999999 |
以下代码仔细设置了使用毫秒的时间戳的格式:
>>> from datetime import datetime
>>> (dt, micro) = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f').split('.')
>>> "%s.%03d" % (dt, int(micro) / 1000)
'2016-02-26 04:37:53.133'
为了获得 OP 想要的确切输出,我们必须去除标点符号:
>>> from datetime import datetime
>>> (dt, micro) = datetime.utcnow().strftime('%Y%m%d%H%M%S.%f').split('.')
>>> "%s%03d" % (dt, int(micro) / 1000)
'20160226043839901'
评论
import datetime
# convert string into date time format.
str_date = '2016-10-06 15:14:54.322989'
d_date = datetime.datetime.strptime(str_date , '%Y-%m-%d %H:%M:%S.%f')
print(d_date)
print(type(d_date)) # check d_date type.
# convert date time to regular format.
reg_format_date = d_date.strftime("%d %B %Y %I:%M:%S %p")
print(reg_format_date)
# some other date formats.
reg_format_date = d_date.strftime("%Y-%m-%d %I:%M:%S %p")
print(reg_format_date)
reg_format_date = d_date.strftime("%Y-%m-%d %H:%M:%S")
print(reg_format_date)
<<<<<<输出>>>>>>>
2016-10-06 15:14:54.322989
<class 'datetime.datetime'>
06 October 2016 03:14:54 PM
2016-10-06 03:14:54 PM
2016-10-06 15:14:54
python -c "from datetime import datetime; print str(datetime.now())[:-3]"
2017-02-09 10:06:37.006
datetime
t = datetime.datetime.now()
ms = '%s.%i' % (t.strftime('%H:%M:%S'), t.microsecond/1000)
print(ms)
14:44:37.134
在 Python 3.6+ 中,您可以设置 isoformat
的:timespec
>>> from datetime import datetime
>>> datetime.utcnow().isoformat(sep=' ', timespec='milliseconds')
'2019-05-10 09:08:53.155'
评论
[:-3]
>>> datetime.fromisoformat('2021-12-08 20:00:00.678900').isoformat(sep=' ', timespec='milliseconds')
'2021-12-08 20:00:00.678'
其他此类解决方案的问题在于它们速度很慢。datetime.utcnow()
更有效的解决方案可能如下所示:
def _timestamp(prec=0):
t = time.time()
s = time.strftime("%H:%M:%S", time.localtime(t))
if prec > 0:
s += ("%.9f" % (t % 1,))[1:2+prec]
return s
在您的案例中的位置(毫秒)。prec
3
该函数最多工作 9 位小数(请注意第二个格式字符串中的数字)。9
如果你想对小数部分进行四舍五入,我建议使用所需的小数位数进行动态构建。"%.9f"
在使用 python f-strings 的 python 3.6 及更高版本中:
from datetime import datetime, timezone
dt = datetime.now(timezone.utc)
print(f"{dt:%Y-%m-%d %H:%M:%S}.{dt.microsecond // 1000:03d}")
特定于格式化毫秒的代码为:
{dt.microsecond // 1000:03d}
格式字符串和微秒到毫秒的转换来自用于 datetime.datetime.isoformat() 的 in https://github.com/python/cpython/blob/master/Lib/datetime.py。{:03d}
// 1000
def _format_time
如果您准备将时间存储在变量中并执行一些字符串操作,那么您实际上可以在不使用 datetime 模块的情况下执行此操作。
>>> _now = time.time()
>>> print ("Time : %s.%s\n" % (time.strftime('%x %X',time.localtime(_now)),
... str('%.3f'%_now).split('.')[1])) # Rounds to nearest millisecond
Time : 05/02/21 01:16:58.676
>>>
%.3f 将四舍五入到最接近的毫秒,如果您想要或多或少的精度,只需更改小数位数
>>> print ("Time : %s.%s\n" % (time.strftime('%x %X',time.localtime(_now)),
... str('%.1f'%_now).split('.')[1])) # Rounds to nearest tenth of a second
Time : 05/02/21 01:16:58.7
>>>
在 Python 2.7 和 3.7 中进行了测试(显然,在 2.x 版本中调用 print 时需要省略括号)。
字段宽度格式规范
UNIX 命令允许指定将精度降低到 3 位:date
%3
$ date '+%Y-%m-%d %H:%M:%S.%3N'
2022-01-01 00:01:23.456
下面是一个可以在 Python 中执行此操作的自定义函数:
from datetime import datetime
def strftime_(fmt: str, dt: datetime) -> str:
tokens = fmt.split("%")
tokens[1:] = [_format_token(dt, x) for x in tokens[1:]]
return "".join(tokens)
def _format_token(dt: datetime, token: str) -> str:
if len(token) == 0:
return ""
if token[0].isnumeric():
width = int(token[0])
s = dt.strftime(f"%{token[1]}")[:width]
return f"{s}{token[2:]}"
return dt.strftime(f"%{token}")
用法示例:
>>> strftime_("%Y-%m-%d %H:%M:%S.%3f", datetime.now())
'2022-01-01 00:01:23.456'
注意:不支持。%%
评论
Instant.parse
strftime('%Y-%m-%dT%H:%M:%S.%fZ')