No datetime.today() / datetime.now() / date.today()
ID |
python.no_datetime_today |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Python |
Tags |
reliability, suspicious-call |
Description
Reports calls to datetime.today(), datetime.now() (no-arg form), and date.today(). These return a "wall clock" without timezone information; the resulting object is naive and silently treats its value as local time, which produces incorrect results during DST transitions and any cross-timezone comparison.
stamp = datetime.today() # FLAW
stamp = datetime.now() # FLAW
stamp = date.today() # FLAW
stamp = datetime.now(timezone.utc) # OK — explicit
stamp = datetime.now(ZoneInfo("Europe/Madrid")) # OK — explicit
Rationale
Naive timestamps look right in unit tests run on a developer machine and silently break in production servers running UTC. The cost of an explicit timezone is one argument; the cost of debugging a cross-timezone bug after the fact is much higher.
Remediation
Always pass an explicit timezone:
from datetime import datetime, timezone
stamp = datetime.now(timezone.utc)
For Python 3.9+ use zoneinfo.ZoneInfo("Region/City") for non-UTC zones. The deprecated datetime.utcnow() returns naive UTC and should also be avoided.