2025, Nov 11 11:00
How to get the current UTC datetime in Python or today at 00:00 as a timezone-aware value
Learn how to get a timezone-aware UTC datetime in Python: either the precise current timestamp or today at 00:00, with examples using the standard library.
Getting the current date in UTC as a timezone-aware Python datetime is a common need, and the standard library gives you everything required without third-party packages. The subtlety is choosing between the exact current timestamp and a date-only value normalized to midnight in UTC, while keeping the result as a datetime.datetime.
Problem statement
You want a datetime.datetime representing “today in UTC” at 00:00, not just a naive date or a local timestamp. Using datetime.date.today() doesn’t help because it has no timezone, and datetime.datetime.today() includes hours, minutes, and seconds. A typical attempt looks like this:
import datetime as dts
utc_midnight = dts.datetime.combine(
dts.datetime.now(dts.UTC).date(),
dts.datetime.min.time(),
tzinfo=dts.UTC,
)
This produces a timezone-aware datetime at 00:00:00 in UTC for the current day.
What’s really going on
The key choice is whether you need the precise current moment in UTC, or a date-only representation anchored to midnight. datetime.now(tz=datetime.UTC) gives you the current UTC timestamp as a timezone-aware datetime. If you need just the date while keeping a datetime type, extract the year, month, and day from that object and construct a new datetime at 00:00 in UTC.
Solution: get the current UTC datetime
To obtain the current date and time in UTC as a timezone-aware datetime:
import datetime as dts
now_aware = dts.datetime.now(tz=dts.UTC)
print(now_aware, type(now_aware))
2025-09-23 12:57:59.065381+00:00 <class 'datetime.datetime'>
Solution: get “today in UTC” as a datetime at 00:00
If what you want is the date-only value for today in UTC, represented as a datetime at midnight:
import datetime as dts
stamp_utc = dts.datetime.now(tz=dts.UTC)
date_only_aware = dts.datetime(stamp_utc.year, stamp_utc.month, stamp_utc.day, tzinfo=dts.UTC)
print(date_only_aware, type(date_only_aware))
2025-09-23 00:00:00+00:00 <class 'datetime.datetime'>
This keeps the object timezone-aware and ensures it represents the start of the day in UTC.
It’s worth noting that including tzinfo in the final constructed datetime is optional if all you care about is the value, but you do need it if the resulting object must remain time zone-aware.
Why this matters
Choosing the right approach avoids mixing naive and aware datetimes and makes intent explicit. Using datetime.now(tz=datetime.UTC) communicates that you need a UTC-aware timestamp. Rebuilding a datetime at midnight from year, month, and day communicates that you want a date-only value but still as a datetime with UTC context.
Wrap-up
Use datetime.now(tz=datetime.UTC) when you need the current moment in UTC as a timezone-aware datetime. When you need “today” in UTC normalized to midnight, construct a new datetime from the extracted year, month, and day with tzinfo=datetime.UTC. If you already have a working combine-based approach, that is also valid; the direct construction is simply concise and clear. Keep tzinfo if you want to preserve timezone awareness.