Используя ваш пример dataframe, мы могли бы:
xtabs(value ~ name + numbers, data = dat1)
Я думаю, что лучше всего пройти через все временные точки pytz и проверить, какой из них соответствует местному часовому поясу, каждый объект часового пояса pytz содержит информацию об utcoffset и tzname, таких как CDT, EST, о той же информации о локальном времени можно получить из time.timezone/altzone
и time.tzname
, и я думаю, что этого достаточно, чтобы правильно совместить локальный часовой пояс в базе данных pytz, например
import time
import pytz
import datetime
local_names = []
if time.daylight:
local_offset = time.altzone
localtz = time.tzname[1]
else:
local_offset = time.timezone
localtz = time.tzname[0]
local_offset = datetime.timedelta(seconds=-local_offset)
for name in pytz.all_timezones:
timezone = pytz.timezone(name)
if not hasattr(timezone, '_tzinfos'):
continue#skip, if some timezone doesn't have info
# go thru tzinfo and see if short name like EDT and offset matches
for (utcoffset, daylight, tzname), _ in timezone._tzinfos.iteritems():
if utcoffset == local_offset and tzname == localtz:
local_names.append(name)
print local_names
вывод:
['America / Atikokan', 'America «Америка / Чикаго», «Америка / Чихуахуа», «Америка / Корал-Харбор», «Америка / «Америка / Индиана», «Америка / Индиана / Маренго», «Америка / Индиана / Индиана», «Америка / Индиана / Индиана», «Америка / Индиана / «Америка / Индиана / Петербург», «Америка / Индиана / Телль_Чита», «Америка / Индиана / Вевай», «Америка / Индиана / Венсенн», «Америка / Индиана / Винамак», «Америка / Индианаполис», «Америка / Икалуит ',' Америка / Кентукки / Луисвилл ',' Америка / Кентукки / L «Америка / Кентукки», «Америка / Нокс_Ин», «Америка / Луисвилл», «Америка / Луисвилл», «Америка / Манагуа», «Америка / Матаморос», «Америка / Меномине», «Америка / «Америка / Мексика», «Америка / Монтеррей», «Америка / Северная_Дакота / Беулах», «Америка / Северная_Дакота / Центр», «Америка / Северная_Дакота / Нью-Салем», «Америка / Ожинага», «Америка / Пангнирунг», «Америка / Режиссер», «Америка / Резолюция», «Америка / Резолюция», «Америка / Тегусигальпа», «Америка / Виннипег», «CST6CDT», «Канада / Центральная», «Мексика /
blockquote>В процессе производства вы можете создать такое сопоставление заранее и сохранить его вместо
Тестирование скрипта после изменения часового пояса:
$ export TZ = 'Австралия / Сидней' $ python get_tz_names.py ['Антарктика / Macquarie', 'Австралия / ACT ',' Австралия / Брисбен ',' Австралия / Канберра ',' Австралия / Керри ',' Австралия / Хобарт ',' Австралия / Линдеман ',' Австралия ia / Melbourne ',' Австралия / NSW ',' Австралия / Квинсленд ',' Австралия / Сидней ',' Австралия / Тасмания ',' Австралия / Виктория ']
blockquote>
Если оценка /etc/localtime
подходит для вас, может получиться следующий трюк: после перевода на python:
> md5sum /etc/localtime
abcdefabcdefabcdefabcdefabcdefab /etc/localtime
> find /usr/share/zoneinfo -type f |xargs md5sum | grep abcdefabcdefabcdefabcdefabcdefab
abcdefabcdefabcdefabcdefabcdefab /usr/share/zoneinfo/Europe/London
abcdefabcdefabcdefabcdefabcdefab /usr/share/zoneinfo/posix/Europe/London
...
Дубликаты могут быть отфильтрованы с использованием только официальных названий регионов «Европа», «Америка» ... Если есть еще дубликаты, вы можете взять кратчайшее имя: -)
Это даст вам имя часового пояса, в зависимости от того, что находится в переменной TZ, или файл локального времени, если он не установлен:
#! /usr/bin/env python
import time
time.tzset
print time.tzname
America/New_York
или Australia/Sydney
. & Quot; БСТ & Quot; может быть Europe/London
или Asia/Dhaka
.
– wberry
10 October 2011 в 20:37
Я предпочитаю следовать немного лучше, чем ковырять значения _xxx
import time, pytz, os
cur_name=time.tzname
cur_TZ=os.environ.get("TZ")
def is_current(name):
os.environ["TZ"]=name
time.tzset()
return time.tzname==cur_name
print "Possible choices:", filter(is_current, pytz.all_timezones)
# optional tz restore
if cur_TZ is None: del os.environ["TZ"]
else: os.environ["TZ"]=cur_TZ
time.tzset()
Модуль tzlocal для Python направлен именно на эту проблему. Он дает согласованные результаты как в Linux, так и в Windows, правильно преобразовывая идентификаторы временного пояса Windows в Olson с использованием сопоставлений CLDR.
Это своего рода обман, я знаю, но переход из '/etc/localtime'
не работает для вас? Например:
>>> import os
>>> '/'.join(os.readlink('/etc/localtime').split('/')[-2:])
'Australia/Sydney'
Надеюсь, что это поможет.
Редактировать: мне понравилась идея @ A.H., в случае, если '/etc/localtime'
не является символической ссылкой. Перевод этого в Python:
#!/usr/bin/env python
from hashlib import sha224
import os
def get_current_olsonname():
tzfile = open('/etc/localtime')
tzfile_digest = sha224(tzfile.read()).hexdigest()
tzfile.close()
for root, dirs, filenames in os.walk("/usr/share/zoneinfo/"):
for filename in filenames:
fullname = os.path.join(root, filename)
f = open(fullname)
digest = sha224(f.read()).hexdigest()
if digest == tzfile_digest:
return '/'.join((fullname.split('/'))[-2:])
f.close()
return None
if __name__ == '__main__':
print get_current_olsonname()
/etc/localtime
не был. Кроме того, я рекомендую немедленно переключиться на 4-сегментный отступ вместо вкладок (или 8 пробелов).
– Matt Joiner
2 December 2011 в 04:34
import pytz
import time
#import locale
import urllib2
yourOlsonTZ = None
#yourCountryCode = locale.getdefaultlocale()[0].split('_')[1]
yourCountryCode = urllib2.urlopen('http://api.hostip.info/country.php').read()
for olsonTZ in [pytz.timezone(olsonTZ) for olsonTZ in pytz.all_timezones]:
if (olsonTZ._tzname in time.tzname) and (str(olsonTZ) in pytz.country_timezones[yourCountryCode]):
yourOlsonTZ = olsonTZ
break
print yourOlsonTZ
Этот код будет взломать наилучшую догадку в вашем часовом поясе Olson, основанный как на вашем имени часового пояса (как в соответствии с модулем time
Python ) и ваш код страны (в соответствии с модулем locale
Python проект hostip.info , который ссылается на ваш IP-адрес и соответствующим образом привязывает вас к геолокации).
Например, просто совпадение с именами Timzone может привести к America/Moncton
, America/Montreal
или America/New_York
для EST (GMT-5). Однако, если ваша страна является США, она ограничит ответ на America/New_York
.
Однако, если ваша страна - Канада, сценарий будет просто по умолчанию высшим канадским результатом (America/Moncton
). Если есть способ доработать это, пожалуйста, оставляйте предложения в комментариях.
en_US
, несмотря на то, что существует en_AU
. Кроме того, мое имя tz 'EST'
, поэтому ваш алгоритм дает мне America/New_York
, но я нахожусь в Australia/Sydney
.
– Matt Joiner
2 December 2011 в 04:30
Я изменил сценарий tcurvelo, чтобы найти правильную форму часового пояса (Continent /..../ City), в большинстве случаев, но вернуть все из них, если не удалось
#!/usr/bin/env python
from hashlib import sha224
import os
from os import listdir
from os.path import join, isfile, isdir
infoDir = '/usr/share/zoneinfo/'
def get_current_olsonname():
result = []
tzfile_digest = sha224(open('/etc/localtime').read()).hexdigest()
test_match = lambda filepath: sha224(open(filepath).read()).hexdigest() == tzfile_digest
def walk_over(dirpath):
for root, dirs, filenames in os.walk(dirpath):
for fname in filenames:
fpath = join(root, fname)
if test_match(fpath):
result.append(tuple(root.split('/')[4:]+[fname]))
for dname in listdir(infoDir):
if dname in ('posix', 'right', 'SystemV', 'Etc'):
continue
dpath = join(infoDir, dname)
if not isdir(dpath):
continue
walk_over(dpath)
if not result:
walk_over(join(infoDir))
return result
if __name__ == '__main__':
print get_current_olsonname()
Вот еще одна возможность, используя PyICU ; который работает для моих целей:
>>> from PyICU import ICUtzinfo
>>> from datetime import datetime
>>> datetime(2012, 1, 1, 12, 30, 18).replace(tzinfo=ICUtzinfo.getDefault()).isoformat()
'2012-01-01T12:30:18-05:00'
>>> datetime(2012, 6, 1, 12, 30, 18).replace(tzinfo=ICUtzinfo.getDefault()).isoformat()
'2012-06-01T12:30:18-04:00'
Здесь он интерпретирует niave datetimes (как будет возвращен запросом базы данных) в локальном часовом поясе.
Одна из проблем заключается в том, что существует несколько «симпатичных имен», таких как «Австралия / Сидней», которые указывают на один и тот же часовой пояс (например, CST).
Поэтому вам нужно будет получить все возможное имена для локального часового пояса, а затем выберите нужное вам имя.
например: для Австралии существует 5 часовых поясов, но больше идентификаторов часовых поясов:
"Australia/Lord_Howe", "Australia/Hobart", "Australia/Currie",
"Australia/Melbourne", "Australia/Sydney", "Australia/Broken_Hill",
"Australia/Brisbane", "Australia/Lindeman", "Australia/Adelaide",
"Australia/Darwin", "Australia/Perth", "Australia/Eucla"
вы должны проверить, есть ли библиотека, которая обертывает TZinfo, для обработки API часового пояса.
, например: для Python, проверьте библиотеку pytz
:
и
http://pypi.python.org/pypi/pytz/
в Python вы можете сделать:
from pytz import timezone
import pytz
In [56]: pytz.country_timezones('AU')
Out[56]:
[u'Australia/Lord_Howe',
u'Australia/Hobart',
u'Australia/Currie',
u'Australia/Melbourne',
u'Australia/Sydney',
u'Australia/Broken_Hill',
u'Australia/Brisbane',
u'Australia/Lindeman',
u'Australia/Adelaide',
u'Australia/Darwin',
u'Australia/Perth',
u'Australia/Eucla']
, но API для Python кажется довольно ограниченным, например он, похоже, не имеет вызова типа Ruby all_linked_zone_names
- который может найти все имена синонимов для данного часового пояса.
Этот проект JavaScript пытается решить ту же проблему на стороне клиента. Он работает, играя «двадцать вопросов» с языком, запрашивая смещение UTC в определенные прошлые времена (чтобы проверить границы летнего времени и т. Д.) И используя эти результаты, чтобы определить, что должно быть местным часовым поясом. К сожалению, я не знаю какого-либо эквивалентного пакета Python, поэтому, если бы кто-то захотел использовать это решение, его пришлось бы портировать на Python.
Хотя эта формула требует обновления каждый раз (в худшем случае) базы данных TZ обновляется, комбинация этого алгоритма и решение, предложенное Anurag Uniyal (сохраняющее только возможности, возвращенные обоими методами), звучит для меня как самый верный способ вычислить эффективный местный часовой пояс. До тех пор, пока существует некоторая разница между UTC-смещением по меньшей мере одного локального времени в любых двух часовых поясах, такая система может правильно выбирать между ними.
Australia/Sydney
.
– CJ Dennis
20 May 2018 в 22:48
if time.daylight and time.localtime().tm_isdst > 0
. Примечание:time.daylight
только указывает, имеет ли локальный часовой пояс DST вообще, он ничего не говорит о текущем состоянии. – jfs 2 August 2013 в 12:36