python - часовой пояс удаленных хостов против локального - PullRequest
1 голос
/ 27 апреля 2011

Я создаю веб-интерфейс для удаленного мониторинга журналов,
мне приходится управлять примерно 10 различными географическими точками. Я столкнулся с трехголовым адом, который у некоторых из вас уже есть.

Есть лиспособ получить из удаленной переменной оболочки HPUX следующую удаленную информацию:

  • zoneinfo (Country / City)
  • UTC + смещение (я могу легко получить это из zoneinfo)

Пока что лучшее, что я мог получить, - это сокращенный часовой пояс ОС (этого достаточно, чтобы итеративно пересечь удаленное время с помощью статически построенной коллекции pytz.common_timezones и выполнить обратное преобразование сокращенных зон в Country / City или I 'я совершенно не в том направлении?)

Я могу легко получить смещение после получения Страны / Города (чего у меня нет)

datetime.now(pytz.timezone('Asia/Dili')).strftime('%Z %z')

'TLT + 0900'

  • получить удаленный сокращенный часовой пояс,

(у Linux гораздо более вменяемый

grep "ZONE=" /etc/sysconfig/clock  

вывод, например,
ZONE = "Europe / London"
пока HP-UX / etc / TIMEZONE uses сокращенные часовые пояса, такие как
TZ = CAT-2

Я бы использовал echo $ TZ, который выводил бы немного больше полезных данных, таких как CAT-2, но некоторые удаленные HP-UX даже не настроили этотаким образом, заставляя меня полагаться на неоднозначную дату RFC822,

date +%z  

CAT

Я посмотрел оба на pytz, datetime.datetime, email.Utils, но, учитывая, что это не может сделать напрямуюпреобразование из сокращенного времени в zoneinfo Страна / Город (pytz допускает обратное)
Стоит ли просто поцарапать этот квест Don Quixote по автообнаружению удаленного часового пояса и просто добавить раскрывающийся список Страна / Город при принятии ввода пользователя, регистрирующего удаленный хост?

РЕДАКТИРОВАТЬ (частичное решение)

на основе ответа @Mike Pennington

from datetime import datetime as dt
from datetime import timedelta as td
from dateutil.relativedelta import *
from email.Utils import mktime_tz, parsedate_tz

hpux_remote_date = 'Thu Apr 28 18:09:20 TLT 2011'
utctimestamp = mktime_tz(parsedate_tz( hpux_remote_date ))  

hpux_dt = dt.fromtimestamp( utctimestamp )
delta_offset = relativedelta(dt.utcnow(), hpux_dt)

hpux_utc = hpux_dt + delta_offset

# Sanity checking to ensure we are correct...
hpux_dt
datetime.datetime(2011, 4, 28, 18, 9, 20)
hpux_utc
datetime.datetime(2011, 4, 28, 9, 9, 22, 229148)

1 Ответ

3 голосов
/ 27 апреля 2011

Вы должны быть в состоянии найти свое смещение по Гринвичу, как это ...

Как смещение по Гринвичу, не учитывая DST

(time.localtime()[3] - time.localtime()[8]) - time.gmtime()[3]

Я нахожусь в центральном времени(GMT - 6), так что это дает -6 в моей системе.

В качестве смещения по Гринвичу, включая компенсацию DST

(time.localtime()[3]) - time.gmtime()[3]

Это дает -5в моей системе.

Вероятно, проще всего воспользоваться вторым вариантом и использовать его для преобразования локального времени HPUX в GMT;затем манипулируйте pytz как требуется.

РЕДАКТИРОВАТЬ

Если вы работаете с текстовым представлением удаленных (не по Гринвичу) временных меток, вероятно, проще работать непосредственно с объектами datetime... У меня нет удобного HPUX, но я предполагаю, что строка даты похожа на мою систему сжатия Debian.

>>> from datetime import datetime as dt
>>> from datetime import timedelta as td
>>> # using os.popen() to simulate the results of a HPUX shell 'date'...
>>> # substitute the real HPUX shell date string in hpux_date
>>> hpux_date = os.popen('date').read().strip()
>>> hpux_dt = dt.strptime(hpux_date, '%a %b %d %H:%M:%S %Z %Y')
>>> # Rounding to the nearest hour because there *will* be slight delay
>>> # between shell string capture and python processing
>>> offset_seconds = ((dt.utcnow() - hpux_dt).seconds//3600)*3600
>>> hpux_gmt = hpux_dt + td(0,offset_seconds)
>>> # Sanity checking to ensure we are correct...
>>> hpux_gmt
datetime.datetime(2011, 4, 27, 17, 21, 58)
>>> hpux_dt
datetime.datetime(2011, 4, 27, 12, 21, 58)
>>> hpux_date
'Wed Apr 27 12:21:58 CDT 2011'
>>>
...