目前我正在记录内容,我正在使用自己的格式化程序和自定义formatTime()
:
def formatTime(self, _record, _datefmt):
t = datetime.datetime.now()
return t.strftime('%Y-%m-%d %H:%M:%S.%f')
我的问题是微秒%f
是六位数。无论如何都要吐出更少的数字,比如微秒的前三位数?
答案 0 :(得分:38)
最简单的方法是使用切片来切断微秒的最后三位数字:
def format_time():
t = datetime.datetime.now()
s = t.strftime('%Y-%m-%d %H:%M:%S.%f')
return s[:-3]
如果你想要实际数字而不仅仅是劈砍,那么它的工作要多一些,但并不可怕:
def format_time():
t = datetime.datetime.now()
s = t.strftime('%Y-%m-%d %H:%M:%S.%f')
tail = s[-7:]
f = round(float(tail), 3)
temp = "%.3f" % f
return "%s%s" % (s[:-7], temp[1:])
答案 1 :(得分:2)
编辑:正如一些人在下面的评论中指出的那样,当微秒值达到999500时,这个解决方案(以及上面的那个)的四舍五入会引入问题,因为999.5被舍入到1000(溢出)。
没有重新实现strftime以支持我们想要的格式(由舍入引起的潜在溢出需要传播到秒,然后是几分钟等),将前截断为前3位数更简单在接受的答案中概述,或使用类似的东西:
'{:03}'.format(int(999999/1000))
- 保留下面的原始答案 -
在我的情况下,我试图格式化一个格式为'ddd'的毫秒的日期戳。我最终用来获得毫秒的解决方案是使用microsecond
对象的datetime
属性,除以1000.0,必要时用零填充,然后用格式对其进行舍入。它看起来像这样:
'{:03.0f}'.format(datetime.now().microsecond / 1000.0)
# Produces: '033', '499', etc.
答案 2 :(得分:2)
此方法应始终返回一个看起来与此完全相同的时间戳(根据输入的dt
对象是否包含时区,有或没有时区):
<强> 2016-08-05T18:18:54.776 + 0000 强>
它需要datetime
个对象作为输入(您可以使用datetime.datetime.now()
生成)。要获得我的示例输出中的时区,您需要import pytz
并传递datetime.datetime.now(pytz.utc)
。
import pytz, datetime
time_format(datetime.datetime.now(pytz.utc))
def time_format(dt):
return "%s:%.3f%s" % (
dt.strftime('%Y-%m-%dT%H:%M'),
float("%.3f" % (dt.second + dt.microsecond / 1e6)),
dt.strftime('%z')
)
我注意到上面的其他一些方法如果有一个(例如0.870
成为0.87
)就会省略尾随零,这会导致我将这些时间戳输入的解析器出现问题。这种方法没有这个问题。
答案 3 :(得分:2)
您可以从微秒中减去当前日期时间。
d = datetime.datetime.now()
current_time = d - datetime.timedelta(microseconds=d.microsecond)
这会将 2021-05-14 16:11:21.916229
变成 2021-05-14 16:11:21
答案 4 :(得分:1)
此方法允许灵活的精度,如果指定的精度太高,将消耗整个微秒值。
def formatTime(self, _record, _datefmt, precision=3):
dt = datetime.datetime.now()
us = str(dt.microsecond)
f = us[:precision] if len(us) > precision else us
return "%d-%d-%d %d:%d:%d.%d" % (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, int(f))
此方法实现舍入到3个小数位:
import datetime
from decimal import *
def formatTime(self, _record, _datefmt, precision='0.001'):
dt = datetime.datetime.now()
seconds = float("%d.%d" % (dt.second, dt.microsecond))
return "%d-%d-%d %d:%d:%s" % (dt.year, dt.month, dt.day, dt.hour, dt.minute,
float(Decimal(seconds).quantize(Decimal(precision), rounding=ROUND_HALF_UP)))
我故意避免使用strftime
方法,因为我宁愿不修改完全序列化的日期时间对象而不重新验证它。这种方式还会显示日期内部结构,以防您想要进一步修改它。
在舍入示例中,请注意Decimal
模块的精度是基于字符串的。
答案 5 :(得分:1)
以下是我使用regexp的解决方案:
import re
# Capture 6 digits after dot in a group.
regexp = re.compile(r'\.(\d{6})')
def to_splunk_iso(dt):
"""Converts the datetime object to Splunk isoformat string."""
# 6-digits string.
microseconds = regexp.search(dt.isoformat()).group(1)
return regexp.sub('.%d' % round(float(microseconds) / 1000), dt.isoformat())
答案 6 :(得分:1)
适用于所有情况的简单解决方案:
def format_time():
t = datetime.datetime.now()
if t.microsecond % 1000 >= 500: # check if there will be rounding up
t = t + datetime.timedelta(milliseconds=1) # manually round up
return t.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
基本上,您首先需要对日期对象本身进行手动舍入,然后可以安全地修剪微秒。
答案 7 :(得分:1)
从 Python 3.6 开始,该语言内置了此功能:
def format_time():
t = datetime.datetime.now()
s = t.isoformat(timespec='milliseconds')
return s
答案 8 :(得分:0)
根据Pablojim评论修复建议的解决方案:
from datetime import datetime
dt = datetime.now()
dt_round_microsec = round(dt.microsecond/1000) #number of zeroes to round
dt = dt.replace(microsecond=dt_round_microsec)
答案 9 :(得分:0)
如果曾经想获得星期几(即“星期日”)及其结果,则切片“ [:-3]”将不起作用。那时您可以选择
dt = datetime.datetime.now()
print("{}.{:03d} {}".format(dt.strftime('%Y-%m-%d %I:%M:%S'), dt.microsecond//1000, dt.strftime("%A")))
#Output: '2019-05-05 03:11:22.211 Sunday'
%H-24小时格式
%I-12小时格式
谢谢
答案 10 :(得分:0)
在这里添加我的 2 美分,因为这种方法将允许您编写微秒格式,就像在 c 样式中编写浮点数一样。它利用了它们都使用 %f
的优势。
import datetime
import re
def format_datetime(date, format):
"""Format a ``datetime`` object with microsecond precision.
Pass your microsecond as you would format a c-string float.
e.g "%.3f"
Args:
date (datetime.datetime): You input ``datetime`` obj.
format (str): Your strftime format string.
Returns:
str: Your formatted datetime string.
"""
# We need to check if formatted_str contains "%.xf" (x = a number)
float_format = r"(%\.\d+f)"
has_float_format = re.search(float_format, format)
if has_float_format:
# make microseconds be decimal place. Might be a better way to do this
microseconds = date.microsecond
while int(microseconds): # quit once it's 0
microseconds /= 10
ms_str = has_float_format.group(1) % microseconds
format = re.sub(float_format, ms_str[2:], format)
return date.strftime(format)
print(datetime.datetime.now(), "%H:%M:%S.%.3f")
# '17:58:54.424'