It is a documented behavior: datetime.now()
returns a naive datetime object and %Z
returns an empty string in such cases. You need an aware datetime object instead.
To print a local timezone abbreviation, you could use tzlocal
module that can return your local timezone as a pytz
tzinfo object that may contain a historical timezone info e.g., from the tz database:
#!/usr/bin/env python
from datetime import datetime
import tzlocal # $ pip install tzlocal
now = datetime.now(tzlocal.get_localzone())
print(now.strftime('%Z'))
# -> MSK
print(now.tzname())
# -> MSK
This code works for timezones with/without daylight saving time. It works around and during DST transitions. It works if the local timezone had different utc offset in the past even if the C library used by python has no access to a historical timezone database on the given platform.
In Python 3.3+, when platform supports it, you could use .tm_zone
attribute, to get the tzname:
>>> import time
>>> time.localtime().tm_zone
'MSK'
Or using datetime
module:
>>> from datetime import datetime, timezone
>>> datetime.now(timezone.utc).astimezone().tzname()
'MSK'
The code is portable but the result may be incorrect on some platforms (without .tm_zone
(datetime
has to use time.tzname
in this case) and with "interesting" timezones).
On older Python versions, on a system with an "uninteresting" timezone, you could use time.tzname
:
>>> import time
>>> is_dst = time.daylight and time.localtime().tm_isdst > 0
>>> time.tzname[is_dst]
'MSK'
An example of an "interesting" timezone is Europe/Moscow timezone in 2010-2015 period.
Similar issues are discussed in Getting computer's UTC offset in Python.