27

I want to print the time zone. I used %Z but it doesn't print:

import datetime
now = datetime.datetime.now()
print now.strftime("%d-%m-%Y")
print now.strftime("%d-%b-%Y")
print now.strftime("%a,%d-%b-%Y %I:%M:%S %Z") # %Z doesn't work

Do I perhaps need to import pytz?

Michael Currie
  • 13,721
  • 9
  • 42
  • 58
ishanka ganepola
  • 315
  • 1
  • 3
  • 6

4 Answers4

48

For me the easiest:

$ python3
>>> import datetime
>>> datetime.datetime.now().astimezone().strftime("%Y-%m-%dT%H:%M:%S %z")
>>> datetime.datetime.now().astimezone().strftime("%Y-%m-%dT%H:%M:%S %Z")
>>> exit()
Mr-IDE
  • 7,051
  • 1
  • 53
  • 59
davgut
  • 624
  • 6
  • 7
  • 5
    This should be the correct answer for the question. – pvsfair Dec 21 '20 at 03:02
  • 1
    @pvsfair except that it may produce wrong result sometimes depending on OS, python version. See [details in my answer](https://stackoverflow.com/a/31304264/4279) – jfs Apr 30 '22 at 09:13
  • Very nice. Had to use single quotes when using in an fstring – Lon Kaut Jun 27 '23 at 15:24
11

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.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
9

now() returns an object of class datetime.datetime, which does not inherently contain information about its time zone. (i.e. it is "naive"; see description of "naive" vs. "aware" date and time objects in the documentation)

According to the documentation,

datetime.datetime.now(tz=None)

Return the current local date and time.

...

If optional argument tz is None or not specified, the timestamp is converted to the platform's local date and time, and the returned datetime object is naive.

To obtain your platform's local timezone, you should use, as you suggest, pytz. Here's Alex Martelli's code to do this:

>>> import datetime
>>> now = datetime.datetime.now()
>>>
>>> from pytz import reference
>>> localtime = reference.LocalTimezone()
>>> localtime.tzname(now)
'Mountain Daylight Time'

You can also get the actual UTC offset, in hours, via:

>>> import time
>>> print(-time.timezone / 3600) # convert from seconds to hours
-7.0

So you could use:

>>> print(now.strftime("%a, %d-%b-%Y %I:%M:%S, " + localtime.tzname(now)))
Wed, 08-Jul-2015 01:27:49, Mountain Daylight Time
Michael Currie
  • 13,721
  • 9
  • 42
  • 58
  • That's because in my code snippet, `now` was not defined. I was assuming you would first run the code from the question to first define `now`. I'll modify my answer to be self-contained, thanks. – Michael Currie Oct 06 '19 at 08:37
2

pytz shouldn't be used. From the help:

NAME
pytz.reference

DESCRIPTION
Reference tzinfo implementations from the Python docs.
Used for testing against as they are only correct for the years
1987 to 2006. Do not use these for real code.

dmigo
  • 2,849
  • 4
  • 41
  • 62
jedo
  • 21
  • 1