Python: выяснить местный часовой пояс - PullRequest
49 голосов
/ 27 апреля 2010

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

>>> local_time=datetime.datetime(2010, 4, 27, 12, 0, 0, 0, 
                                 tzinfo=pytz.timezone('Israel'))

Я хочу найти автоматический инструмент, который заменит tzinfo=pytz.timezone('Israel') на текущий часовой пояс.

Есть идеи?

Ответы [ 15 ]

1 голос
/ 26 февраля 2019

Вы можете быть счастливы с маятником

>>> pendulum.datetime(2015, 2, 5, tz='local').timezone.name
'Israel'

Маятник имеет хорошо разработанный API для манипулирования датами. Все осведомлено о TZ.

1 голос
/ 15 ноября 2018
now_dt = datetime.datetime.now()
utc_now = datetime.datetime.utcnow()
now_ts, utc_ts = map(time.mktime, map(datetime.datetime.timetuple, (now_dt, utc_now)))
offset = int((now_ts - utc_ts) / 3600)

надеюсь, это поможет вам.

1 голос
/ 12 марта 2013

Для простых вещей можно использовать следующую реализацию tzinfo, которая запрашивает у ОС смещение часового пояса:

import datetime
import time

class LocalTZ(datetime.tzinfo):
    _unixEpochOrdinal = datetime.datetime.utcfromtimestamp(0).toordinal()

    def dst(self, dt):
        return datetime.timedelta(0)

    def utcoffset(self, dt):
        t = (dt.toordinal() - self._unixEpochOrdinal)*86400 + dt.hour*3600 + dt.minute*60 + dt.second + time.timezone
        utc = datetime.datetime(*time.gmtime(t)[:6])
        local = datetime.datetime(*time.localtime(t)[:6])
        return local - utc


print datetime.datetime.now(LocalTZ())
print datetime.datetime(2010, 4, 27, 12, 0, 0, tzinfo=LocalTZ())

# If you're in the EU, the following datetimes are right on the DST change.
print datetime.datetime(2013, 3, 31, 0, 59, 59, tzinfo=LocalTZ())
print datetime.datetime(2013, 3, 31, 1, 0, 0, tzinfo=LocalTZ())
print datetime.datetime(2013, 3, 31, 1, 59, 59, tzinfo=LocalTZ())

# The following datetime is invalid, as the clock moves directly from
# 01:59:59 standard time to 03:00:00 daylight savings time.
print datetime.datetime(2013, 3, 31, 2, 0, 0, tzinfo=LocalTZ())

print datetime.datetime(2013, 10, 27, 0, 59, 59, tzinfo=LocalTZ())
print datetime.datetime(2013, 10, 27, 1, 0, 0, tzinfo=LocalTZ())
print datetime.datetime(2013, 10, 27, 1, 59, 59, tzinfo=LocalTZ())

# The following datetime is ambigous, as 02:00 can be either DST or standard
# time. (It is interpreted as standard time.)
print datetime.datetime(2013, 10, 27, 2, 0, 0, tzinfo=LocalTZ())
0 голосов
/ 04 октября 2015

Во-первых, обратите внимание, что вопрос представляет неправильную инициализацию осведомленного объекта datetime:

>>> local_time=datetime.datetime(2010, 4, 27, 12, 0, 0, 0,
...                                  tzinfo=pytz.timezone('Israel'))

создает недопустимый экземпляр. Проблему можно увидеть, рассчитав смещение UTC получившегося объекта:

>>> print(local_time.utcoffset())
2:21:00

(Обратите внимание на результат, который составляет нечетную долю часа.)

Чтобы правильно инициализировать время и дату, используя pytz, следует использовать метод localize() следующим образом:

>>> local_time=pytz.timezone('Israel').localize(datetime.datetime(2010, 4, 27, 12))
>>> print(local_time.utcoffset())
3:00:00

Теперь, если вам требуется локальный часовой пояс pytz в качестве новой tzinfo, вы должны использовать пакет tzlocal, как объяснили другие, но если все, что вам нужно, это экземпляр с правильным смещением и сокращением локального часового пояса, то переходите на Python 3.3 Вы можете вызвать метод astimezone() без аргументов, чтобы преобразовать осведомленный экземпляр datetime в местный часовой пояс:

>>> local_time.astimezone().strftime('%Y-%m-%d %H:%M %Z %z')
'2010-04-27 05:00 EDT -0400'
0 голосов
/ 01 апреля 2015

tzlocal от dateutil .

Пример кода приведен ниже. Последняя строка подходит для использования в именах файлов.

>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>> str(datetime.now(tzlocal()))
'2015-04-01 11:19:47.980883-07:00'
>>> str(datetime.now(tzlocal())).replace(' ','-').replace(':','').replace('.','-')
'2015-04-01-111947-981879-0700'
>>> 
...