How can I get a human-readable timezone name in Py

2020-02-05 12:42发布

In a Python project I'm working on, I'd like to be able to get a "human-readable" timezone name of the form America/New_York, corresponding to the system local timezone, to display to the user. Every piece of code I've seen that accesses timezone information only returns either a numeric offset (-0400) or a letter code (EDT) or sometimes both. Is there some Python library that can access this information, or if not that, convert the offset/letter code into a human-readable name?

If there's more than one human-readable name corresponding to a particular timezone, either a list of the possible results or any one of them is fine, and if there is no human-readable name corresponding to the current time zone, I'll take either an exception or None or [] or whatever.

6条回答
不美不萌又怎样
2楼-- · 2020-02-05 13:01

http://pytz.sourceforge.net/ may be of help. If nothing else, you may be able to grab a list of all of the timezones and then iterate through until you find one that matches your offset.

查看更多
女痞
3楼-- · 2020-02-05 13:02

I'd like to be able to get a "human-readable" timezone name of the form America/New_York, corresponding to the system local timezone, to display to the user.

There is tzlocal module that returns a pytz tzinfo object that corresponds to the system local timezone:

#!/usr/bin/env python
import tzlocal  # $ pip install tzlocal

print(tzlocal.get_localzone().zone) # display "human-readable" name (tzid)
# -> Europe/Moscow

To answer the question in the title (for people from google), you could use %Z%z to print the local time zone info:

#!/usr/bin/env python
import time

print(time.strftime('%Z%z'))
# -> MSK+0300

It prints the current timezone abbreviation and the utc offset corresponding to your local timezone.

查看更多
戒情不戒烟
4楼-- · 2020-02-05 13:03

The following generates a defaultdict mapping timezone offsets (e.g. '-0400') and abbreviations (e.g. 'EDT') to common geographic timezone names (e.g. 'America/New_York').

import os
import dateutil.tz as dtz
import pytz
import datetime as dt
import collections

result=collections.defaultdict(list)
for name in pytz.common_timezones:
    timezone=dtz.gettz(name)
    now=dt.datetime.now(timezone)
    offset=now.strftime('%z')
    abbrev=now.strftime('%Z')
    result[offset].append(name)
    result[abbrev].append(name)    
print(result)

Note that timezone abbreviations can have vastly different meanings. For example, 'EST' could stand for Eastern Summer Time (UTC+10) in Australia, or Eastern Standard Time (UTC-5) in North America.

Also, the offsets and abbreviations may change for regions that use daylight standard time. So saving the static dict may not provide the correct timezone name 365 days a year.

查看更多
Deceive 欺骗
5楼-- · 2020-02-05 13:05

If you want only literally what you asked for, "the timezone name of the form America/New_York, corresponding to the system local timezone", and if you only care about Linux (and similar), then this should do the job:

import os
import os.path
import sys 

def main(argv):
  tzname = os.environ.get('TZ')
  if tzname:
    print tzname
  elif os.path.exists('/etc/timezone'):
    print file('/etc/timezone').read()
  else:
    sys.exit(1)

if __name__ == '__main__':
  main(sys.argv)

Of course it would be nicer to have a library that encapsulates this in a cleaner way, and that perhaps handles the other cases you mention in comments like already having a tzinfo object. I think you can do that with pytz mentioned by Amber but it's not obvious to me just how...

查看更多
时光不老,我们不散
6楼-- · 2020-02-05 13:16

This may not have been around when this question was originally written, but here is a snippet to get the time zone official designation:

>>> eastern = timezone('US/Eastern')
>>> eastern.zone
'US/Eastern'

Further, this can be used with a non-naive datetime object (aka a datetime where the actual timezone has been set using pytz.<timezone>.localize(<datetime_object>) or datetime_object.astimezone(pytz.<timezone>) as follows:

>>> import datetime, pytz
>>> todaynow = datetime.datetime.now(tz=pytz.timezone('US/Hawaii'))
>>> todaynow.tzinfo # turned into a string, it can be split/parsed
<DstTzInfo 'US/Hawaii' HST-1 day, 14:00:00 STD>
>>> todaynow.strftime("%Z")
'HST'
>>> todaynow.tzinfo.zone
'US/Hawaii'

This is, of course, for the edification of those search engine users who landed here. ... See more at the pytz module site.

查看更多
一夜七次
7楼-- · 2020-02-05 13:19

Check out python-dateutil

py> from dateutil.tz import *
py> ny = gettz('America/New York')
py> ny._filename
'/usr/share/zoneinfo/America/New_York'
py> ny._filename.split('/', 4)[-1]
'America/New_York'
查看更多
登录 后发表回答