![github-actions[bot]](/assets/img/avatar_default.png)
* Create rule S6903 * Create rule S6903: Using timezone aware "datetime"s should be preferred over using "datetime.datetime.utcnow" and "datetime.datetime.utcfromtimestamp" * Fix after review * Minor updates --------- Co-authored-by: joke1196 <joke1196@users.noreply.github.com> Co-authored-by: David Kunzmann <david.kunzmann@sonarsource.com> Co-authored-by: Guillaume Dequenne <guillaume.dequenne@sonarsource.com>
61 lines
1.8 KiB
Plaintext
61 lines
1.8 KiB
Plaintext
This rule raises an issue when the functions `datetime.datetime.utcnow` or `datetime.datetime.utcfromtimestamp` are used.
|
|
|
|
== Why is this an issue?
|
|
|
|
Python's `datetime` API provide several different ways to create `datetime` objects. One possibility is the to use
|
|
`datetime.datetime.utcnow` or `datetime.datetime.utcfromtimestamp` functions. The issue with these two functions is they are not time zone aware, even if their name would suggest otherwise.
|
|
|
|
Using these functions could cause issue as they may not behave as expected, for example:
|
|
|
|
[source,python]
|
|
----
|
|
from datetime import datetime
|
|
timestamp = 1571595618.0
|
|
date = datetime.utcfromtimestamp(timestamp)
|
|
date_timestamp = date.timestamp()
|
|
|
|
assert timestamp == date_timestamp
|
|
----
|
|
|
|
This assertion will fail if the system locale is not set to UTC.
|
|
For this reason these 2 functions are deprecated in Python 3.12.
|
|
|
|
== How to fix it
|
|
|
|
To fix this issue, prefer the usage of a timezone-aware datetime.
|
|
|
|
=== Code examples
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,python,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
from datetime import datetime
|
|
|
|
datetime.utcnow() # Noncompliant
|
|
|
|
timestamp = 1571595618.0
|
|
datetime.utcfromtimestamp(timestamp) # Noncompliant
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,python,diff-id=1,diff-type=compliant]
|
|
----
|
|
from datetime import datetime, timezone
|
|
|
|
datetime.now(timezone.utc) # Compliant
|
|
|
|
timestamp = 1571595618.0
|
|
datetime.fromtimestamp(timestamp, timezone.utc) # Compliant
|
|
----
|
|
== Resources
|
|
=== Documentation
|
|
|
|
* Python documentation - https://docs.python.org/3/library/datetime.html#datetime.datetime.utcnow[utcnow reference]
|
|
* Python documentation - https://docs.python.org/3/library/datetime.html#datetime.datetime.utcfromtimestamp[utcfromtimestamp reference]
|
|
|
|
=== Articles & blog posts
|
|
|
|
* Paul Ganssle blog - https://blog.ganssle.io/articles/2019/11/utcnow.html[Stop using utcnow and utcfromtimestamp]
|