比较字符串日期时间与ISO日期时间格式

huangapple go评论109阅读模式
英文:

Compare string datetime with ISO datetime format

问题

我正在尝试在Python代码中比较ISO日期时间和字符串日期时间。我从Azure Cloud的JSON响应中获取日期时间,需要将其与前24小时的日期时间进行比较。我在字符串转换为日期时间的过程中遇到了问题。

以下是代码:

from datetime import datetime, timedelta

target_date = datetime.now() - timedelta(hours=24)
print(target_date.isoformat())
print(type(target_date))

createdOn = "2022-10-25T21:41:27.2824196Z"
post_time = datetime.strptime(createdOn, "%Y-%m-%dT%H:%M:%S.%f%z")
print(post_time)

我需要比较/检查createdOn是否大于target_date。运行代码时,我遇到了以下错误:

2023-08-07T13:22:11.914140
<class 'datetime.datetime'>
Traceback (most recent call last):
  File "/Users/Documents/GitHub/Mylabs/mytest.py", line 10, in <module>
    post_time = datetime.strptime(createdOn, "%Y-%m-%dT%H:%M:%S.%f%z")
  File "/Users/.pyenv/versions/3.8.17/lib/python3.8/_strptime.py", line 568, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
  File "/Users/.pyenv/versions/3.8.17/lib/python3.8/_strptime.py", line 349, in _strptime
    raise ValueError("time data %r does not match format %r" %
ValueError: time data '2022-10-25T21:41:27.2824196Z' does not match format '%Y-%m-%dT%H:%M:%S.%f%z'

请注意,我只会返回翻译好的部分,不会回答关于翻译的问题。

英文:

I am trying to compare ISO DateTime with string datetime in Python code. I am getting datetime in JSON response from Azure Cloud which I need to compare to the last 24 hours before datetime. I am stuck at string-to-datetime conversion.

Here is the code

from datetime import datetime, timedelta

target_date = datetime.now() - timedelta (hours=24)
print(target_date.isoformat())
print(type(target_date))

createdOn = &quot;2022-10-25T21:41:27.2824196Z&quot;
post_time = datetime.strptime(createdOn, &quot;%Y-%m-%dT%H:%M:%S.%f%z&quot;)
print(post_time)

I need to compare/check if createdOn is greater than target_date. While running the code, I am getting below error

    2023-08-07T13:22:11.914140
&lt;class &#39;datetime.datetime&#39;&gt;
Traceback (most recent call last):
  File &quot;/Users/Documents/GitHub/Mylabs/mytest.py&quot;, line 10, in &lt;module&gt;
    post_time = datetime.strptime(createdOn, &quot;%Y-%m-%dT%H:%M:%S.%f%z&quot;)
  File &quot;/Users/.pyenv/versions/3.8.17/lib/python3.8/_strptime.py&quot;, line 568, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
  File &quot;/Users/.pyenv/versions/3.8.17/lib/python3.8/_strptime.py&quot;, line 349, in _strptime
    raise ValueError(&quot;time data %r does not match format %r&quot; %
ValueError: time data &#39;2022-10-25T21:41:27.2824196Z&#39; does not match format &#39;%Y-%m-%dT%H:%M:%S.%f%z&#39;

答案1

得分: 1

你可能会发现使用python-dateutil来自PyPI更容易进行日期解析。它可以解析绝大多数已知的日期格式,并且可以让你的工作变得更简单。

一旦在PyPI中安装了它,就可以像这样轻松地使用它:

from datetime import datetime, timedelta, timezone

# 为了方便在代码中引用,由回答者完成。
from dateutil.parser import parse as dateparse

target_date = datetime.now().astimezone(timezone.utc) - timedelta(hours=24)
print(target_date.isoformat())
print(type(target_date))

createdOn = "2022-10-25T21:41:27.2824196Z"
post_time = dateparse(createdOn)
print(post_time)

它可以有效地解决手动解析日期的麻烦,确保能正确解析日期时间格式,并且可以与不同格式的时间戳一起使用。虽然它不能解决你的strptime问题,但它可以更容易地解析日期和时间戳。(这只是dateutil可以做的众多功能之一,但它在这方面表现得非常出色)

由于dateutil的解析函数返回一个datetime对象,你实际上可以直接比较这两个datetime对象。但是,你应该确保target_date的时间是datetime.now.astimezone(timezone.utc)(这就是为什么导入中包含时区信息),以确保你比较的是两个时区感知的datetime对象。

然后你可以直接比较它们。

例如,print(target_date > post_time)将打印一个布尔值,如果target_date晚于或等于post_time,则为True。


Python 3.11及更高版本具有更简便的转换机制fromisoformat,但如果你使用的是早期版本(如Python 3.8),使用dateutil将是更优秀的解析方法。

英文:

You might find it easier to use python-dateutil form PyPI to do the date parsing. This will parse the vast majority of known date formats and get things a little easier for you.

Once installed in PyPI, it can easily be used like so:

from datetime import datetime, timedelta, timezone

# Done by answerer for easier reference in code.
from dateutil.parser import parse as dateparse

target_date = datetime.now().astimezone(timezone.utc) - timedelta (hours=24)
print(target_date.isoformat())
print(type(target_date))

createdOn = &quot;2022-10-25T21:41:27.2824196Z&quot;
post_time = dateparse(createdOn)
print(post_time)

Effectively, it takes the headache of parsing manually out of the equation so that you know it will parse the datetime format properly and "just work" with varying formats of timestamps. While it doesn't solve your strptime issue it makes it easier to parse dates and timestamps. (This is just one of the many things that dateutil can do, but it does this very well)

Since dateutil's parser function returns a datetime object you can actually compare the two datetimes directly. However, you should make sure that your time for target_date is datetime.now.astimezone(timezone.utc) (which is why timezone is in the imports) to make sure you are comparing two timezone aware datetimes.

Then you can compare them directly.

print(target_date &gt; post_time) for example will print a boolean value if target_date is later than or equal to post_time.


Python 3.11 and later have a fromisoformat mechanism for easier conversion, however if you are using anything earlier (like Python 3.8), using dateutil will be the superior parser method.

答案2

得分: -3

你遇到的错误是因为格式字符串中的%z指令不支持时区偏移中的冒号。你可以从字符串的时区偏移中删除冒号,并使用%f代替%f%z来单独解析小数秒。以下是修改后的代码:

from datetime import datetime, timedelta

target_date = datetime.now() - timedelta(hours=24)
print(target_date.isoformat())
print(type(target_date))

createdOn = "2022-10-25T21:41:27.2824196Z"
createdOn = createdOn[:-3] + createdOn[-2:]  # 从时区偏移中删除冒号
post_time = datetime.strptime(createdOn, "%Y-%m-%dT%H:%M:%S.%fZ")
print(post_time)

通过使用字符串切片,将createdOn字符串修改为删除时区偏移中的冒号。然后,使用格式"%Y-%m-%dT%H:%M:%S.%fZ"解析修改后的字符串。%Z指令用于匹配表示时区偏移的字符"Z"。

通过这些更改,代码现在应该能够将createdOn字符串解析为一个datetime对象,而不会引发任何错误。

英文:

The error you encountered is because the %z directive in the format string does not support the colon in the timezone offset. You can remove the colon from the timezone offset in your string, and use %f instead of %f%z to parse the fractional seconds separately. Here's the modified code:

from datetime import datetime, timedelta

target_date = datetime.now() - timedelta(hours=24)
print(target_date.isoformat())
print(type(target_date))

createdOn = &quot;2022-10-25T21:41:27.2824196Z&quot;
createdOn = createdOn[:-3] + createdOn[-2:]  # Remove colon from timezone offset
post_time = datetime.strptime(createdOn, &quot;%Y-%m-%dT%H:%M:%S.%fZ&quot;)
print(post_time)

The createdOn string is modified by removing the colon from the timezone offset using string slicing. Then, the modified string is parsed using the format &quot;%Y-%m-%dT%H:%M:%S.%fZ&quot;. The %Z specifier is used to match the "Z" character representing the timezone offset.

With these changes, the code should now be able to parse the createdOn string into a datetime object without raising any errors.

huangapple
  • 本文由 发表于 2023年8月9日 04:25:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76862982.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定