【问题标题】:Is there a way to fix this datetime error?有没有办法解决这个日期时间错误?
【发布时间】:2022-01-21 22:13:42
【问题描述】:

我收到此错误:

ValueError: time data '2022-01-20T15:30:57.2648531Z' does not match format '%Y-%m-%dT%H:%M:%S.%fZ'

这是我的代码:

import datetime
 
date_string = '2022-01-20T15:30:57.2648531Z'
date_format = datetime.datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%S.%fZ")
unix_time = datetime.datetime.timestamp(date_format)
print(unix_time)

我已经测试了删除时间数据中的最终数字并且它有效。看来您在毫秒位置只能有 6 个数字。有没有办法绕过/解决这个问题?

【问题讨论】:

  • 你应该加回你从答案的 sn-p 中删除的 1,这样人们就可以复制错误。
  • 根据文档:docs.python.org/3/library/…“当与 strptime() 方法一起使用时,%f 指令接受 1 到 6 位数字和右侧的零填充。”
  • 我发送的代码是给我错误的代码,如果这就是你的意思
  • @NotClooudy 我已经编辑了你问题中的代码,以便它产生你已经得到的错误。
  • 那么有没有办法绕过这个?还是有其他方法可以转换为 unix

标签: python datetime


【解决方案1】:

不幸的是,datetime.datetime 类仅支持从 0999999 的微秒。观察:

>>> import datetime
>>> datetime.datetime(2022, 1, 20, 15, 30, 57, 2648531)
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    datetime.datetime(2022, 1, 20, 15, 30, 57, 2648531)
ValueError: microsecond must be in 0..999999
>>> 

但是,即使您竭尽全力将微秒与字符串分开以添加到unix_time,您仍然会遇到丢失1 的问题:

import datetime
 
date_string = '2022-01-20T15:30:57.2648531Z'
index = date_string.rindex(".")
ms = float(date_string[index: -1])
date_format = datetime.datetime.strptime(date_string[:index], "%Y-%m-%dT%H:%M:%S")
unix_time = datetime.datetime.timestamp(date_format) + ms
print(unix_time)

输出:

1642721457.264853

那是因为 python 根本不支持这种浮点精度:

>>> 1642721457.2648531
1642721457.264853

【讨论】:

  • 当我使用支持纳秒的 java.time 从 java rest apis 读取数据时,我总是遇到这个问题。实际用处不大,但我必须去掉时区部分,然后将 %f 部分减少到 6 位,然后重新添加时区部分。
【解决方案2】:

看来你在毫秒位置只能有 6 个数字

实际上是微秒,%f 说明符匹配一个 6 位数的微秒值。如果您有一个 7 位数字,则精度超过 1 微秒。

datetime 对象不支持比微秒更高的精度,所以你可以扔掉最后一个数字。您可以通过多种方式执行此操作。由于根据您的格式说明符,您的字符串应始终具有相同的长度,因此您可以在转换之前简单地对其进行修剪。

import datetime 

date_string = '2022-01-20T15:30:57.2648531Z'
date_string = date_string[:26] # trim anything past the 6th decimal digit

d = datetime.datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%S.%f")
print(d.timestamp())

由于您的日期是 ISO 格式,您也可以使用datetime.datetime.fromisoformat(),这应该会让您的生活更轻松:

import datetime 

date_string = '2022-01-20T15:30:57.2648531Z'
date_string = date_string[:26] # trim anything past the 6th decimal digit

d = datetime.datetime.fromisoformat(date_string)
print(d.timestamp())

【讨论】:

    【解决方案3】:

    使用datetime 只会让您到目前为止(6 位数)。请改用pd.to_datetime

    unix_time = pd.to_datetime(date_string)
    print(unix_time.value)
    

    输出:

    1642692657264853100
    

    【讨论】:

    • 请注意,最终值不是 OP 所寻找的,您应该将其除以 10**9,因为 OP 想要以秒为单位的结果。
    • 这是不可能的,它会被截断。
    猜你喜欢
    • 2020-12-13
    • 1970-01-01
    • 2021-05-28
    • 2021-06-05
    • 2021-02-11
    • 2020-02-25
    • 2020-02-18
    • 2020-08-10
    • 2019-10-02
    相关资源
    最近更新 更多