How do I get a value of datetime.today() in Python that is timezone aware?
In the standard library, there is no cross-platform way to create aware timezones without creating your own timezone class. (Edit: Python 3.9 introduces zoneinfo
in the standard library which does provide this functionality.)
On Windows, there's win32timezone.utcnow()
, but that's part of pywin32. I would rather suggest to use the pytz library, which has a constantly updated database of most timezones.
Working with local timezones can be very tricky (see "Further reading" links below), so you may rather want to use UTC throughout your application, especially for arithmetic operations like calculating the difference between two time points.
You can get the current date/time like so:
import pytz
from datetime import datetime
datetime.utcnow().replace(tzinfo=pytz.utc)
Mind that datetime.today()
and datetime.now()
return the local time, not the UTC time, so applying .replace(tzinfo=pytz.utc)
to them would not be correct.
Another nice way to do it is:
datetime.now(pytz.utc)
which is a bit shorter and does the same.
Further reading/watching why to prefer UTC in many cases:
- pytz documentation
- What Every Developer Should Know About Time – development hints for many real-life use cases
- The Problem with Time & Timezones - Computerphile – funny, eye-opening explanation about the complexity of working with timezones (video)
How to make a timezone aware datetime object
In general, to make a naive datetime timezone-aware, use the localize method:
import datetime
import pytz
unaware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0)
aware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0, pytz.UTC)
now_aware = pytz.utc.localize(unaware)
assert aware == now_aware
For the UTC timezone, it is not really necessary to use localize
since there is no daylight savings time calculation to handle:
now_aware = unaware.replace(tzinfo=pytz.UTC)
works. (.replace
returns a new datetime; it does not modify unaware
.)
Python datetime.now() with timezone
If you are using Python 3.2 or newer, you need to create a datetime.timezone()
object; it takes an offset as a datetime.timedelta()
:
from datetime import datetime, timezone, timedelta
timezone_offset = -8.0 # Pacific Standard Time (UTC−08:00)
tzinfo = timezone(timedelta(hours=timezone_offset))
datetime.now(tzinfo)
For earlier Python versions, it'll be easiest to use an external library to define a timezone object for you.
The dateutil
library includes objects to take a numerical offset to create a timezone object:
from dateutil.tz import tzoffset
timezone_offset = -8.0 # Pacific Standard Time (UTC−08:00)
tzinfo = tzoffset(None, timezone_offset * 3600) # offset in seconds
datetime.now(tzinfo)
Why does datetime.datetime.utcnow() not contain timezone information?
That means it is timezone naive, so you can't use it with datetime.astimezone
you can give it a timezone like this
import pytz # 3rd party: $ pip install pytz
u = datetime.utcnow()
u = u.replace(tzinfo=pytz.utc) #NOTE: it works only with a fixed utc offset
now you can change timezones
print(u.astimezone(pytz.timezone("America/New_York")))
To get the current time in a given timezone, you could pass tzinfo to datetime.now()
directly:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
print(datetime.now(pytz.timezone("America/New_York")))
It works for any timezone including those that observe daylight saving time (DST) i.e., it works for timezones that may have different utc offsets at different times (non-fixed utc offset). Don't use tz.localize(datetime.now())
-- it may fail during end-of-DST transition when the local time is ambiguous.
Python Datetime : use strftime() with a timezone-aware date
In addition to what @Slam has already answered:
If you want to output the UTC time without any offset, you can do
from datetime import timezone, datetime, timedelta
d = datetime(2009, 4, 19, 21, 12, tzinfo=timezone(timedelta(hours=-2)))
d.astimezone(timezone.utc).strftime('%Y-%m-%d %H:%M:%S.%f')
See datetime.astimezone in the Python docs.
Python. How to create a local datetime with datetime.today()
I'm guessing that the datetime
from your frontend is in UTC. Doing a replace doesn't actually convert the datetime. It uses the data/hour/etc. and just uses a new timezone.
When you call datetime.today()
, you create a naive datetime without any timezone info. When you do a replace
on that, it's not actually doing a conversion either, it's just assuming the date you gave it is already in the timezone you provided, the same as the replace you did on the server time.
To actually convert datetimes to another timezone, you need to use astimezone
. If the datetime from the server is also naive and doesn't specify a timezone, astimezone
will error. To fix that. add a timezone of UTC
first.
time_from_frontend = time_from_frontend.replace(tzinfo=pytz.timezone('UTC'))
converted_server_time = time_from_frontend.astimezone(my_timezone)
Python: Figure out local timezone
Try dateutil, which has a tzlocal type that does what you need.
How do I print a datetime in the local timezone?
Think your should look around: datetime.astimezone()
http://docs.python.org/library/datetime.html#datetime.datetime.astimezone
Also see pytz module - it's quite easy to use -- as example:
eastern = timezone('US/Eastern')
http://pytz.sourceforge.net/
Example:
from datetime import datetime
import pytz
from tzlocal import get_localzone # $ pip install tzlocal
utc_dt = datetime(2009, 7, 10, 18, 44, 59, 193982, tzinfo=pytz.utc)
print(utc_dt.astimezone(get_localzone())) # print local time
# -> 2009-07-10 14:44:59.193982-04:00
Related Topics
Should I Use 'Has_Key()' or 'In' on Python Dicts
How to Build 32Bit Python 2.6 on 64Bit Linux
Python Linux Dmidecode, How to Obtain Hw Info by Parsing
Python in Raw Mode Stdin Print Adds Spaces
Pickled File Won't Load on MAC/Linux
Python: Get Output of the Shell Command 'History'
Extract Text from Xml Documents in Python
How to Automatically Install Required Packages from a Python Script as Necessary
Detect Socket Hangup Without Sending or Receiving
Curses-Like Library for Cross-Platform Console App in Python
Prevent Sleep Mode Python (Wakelock on Python)
Running a Linux Command from Python
Shutting Down Computer (Linux) Using Python
Popen.Communicate() Throws Oserror: "[Errno 10] No Child Processes"