71

get local timezone nameを使用できますtime.tznameが、その名前は と互換性がありませんpytz.timezone

実際、 によって返される名前time.tznameはあいまいです。このメソッドは('CST', 'CST')私のシステムに戻りますが、「CST」は 4 つのタイムゾーンを示すことができます。

  • 中部時間帯 (北アメリカ) - 北アメリカの中部時間帯で観察
  • 中国標準時
  • 中原標準時 - 「中原標準時」という用語は現在、台湾ではめったに使用されていません
  • オーストラリア中部標準時 (ACST)
4

6 に答える 6

83

tzlocalモジュールは、ローカル タイムゾーンに対応する pytz tzinfo のオブジェクトを返します。

import time
from datetime import datetime

import pytz # $ pip install pytz
from tzlocal import get_localzone # $ pip install tzlocal

# get local timezone    
local_tz = get_localzone() 

# test it
# utc_now, now = datetime.utcnow(), datetime.now()
ts = time.time()
utc_now, now = datetime.utcfromtimestamp(ts), datetime.fromtimestamp(ts)

local_now = utc_now.replace(tzinfo=pytz.utc).astimezone(local_tz) # utc -> local
assert local_now.replace(tzinfo=None) == now

地方時があいまいな場合がある夏時間の移行中にも機能します。

local_tzローカル タイムゾーンの utc オフセットがその時点で異なっていたとしても、過去の日付に対しても機能します。dateutil.tz.tzlocal()この場合、ベースのソリューションは失敗します。たとえば、ヨーロッパ/モスクワのタイムゾーン (2013 年の例) では失敗します。

>>> import os, time
>>> os.environ['TZ'] = 'Europe/Moscow'
>>> time.tzset()
>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>> from tzlocal import get_localzone
>>> dateutil_tz = tzlocal()
>>> tzlocal_tz = get_localzone()
>>> datetime.fromtimestamp(0, dateutil_tz)                              
datetime.datetime(1970, 1, 1, 4, 0, tzinfo=tzlocal())
>>> datetime.fromtimestamp(0, tzlocal_tz)
datetime.datetime(1970, 1, 1, 3, 0, tzinfo=<DstTzInfo 'Europe/Moscow' MSK+3:00:00 STD>)

dateutil は、1970-01-01 の正しい UTC+3 ではなく、間違ったUTC+4 オフセットを返します。

2017年にこれにぶつかった人にとって dateutil.tz.tzlocal()は、まだ壊れています。上記の例は、現在の utf オフセットがモスクワの UTC+3 であるため (偶然にも 1970 年の utc オフセットに等しい) 動作します。エラーを示すために、utc オフセットが UTC+4 の日付を選択できます。

>>> import os, time
>>> os.environ['TZ'] = 'Europe/Moscow'
>>> time.tzset()
>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>> from tzlocal import get_localzone
>>> dateutil_tz = tzlocal()
>>> tzlocal_tz = get_localzone()
>>> ts = datetime(2014, 6,1).timestamp() # get date in 2014 when gmtoff=14400 in Moscow
>>> datetime.fromtimestamp(ts, dateutil_tz)
datetime.datetime(2014, 5, 31, 23, 0, tzinfo=tzlocal())
>>> datetime.fromtimestamp(ts, tzlocal_tz)
datetime.datetime(2014, 6, 1, 0, 0, tzinfo=<DstTzInfo 'Europe/Moscow' MSK+4:00:00 STD>)

dateutil は、2014-06-01 の正しい UTC+4 ではなく、間違ったUTC+3 オフセットを返します。

于 2013-06-28T13:26:26.900 に答える
38

パッケージのtzlocal関数を使用します:python-dateutil

from dateutil.tz import tzlocal

localtimezone = tzlocal()

内部的にはtime.timezoneand time.altzone( に基づいて切り替えtime.daylight) を使用するクラスですが、そこから適切な timezone オブジェクトを作成します。

タイムゾーンの代わりにこれを使用します。pytz

別の方法は、代わりにオペレーティング システムから現在構成されているタイムゾーンを読み取ることですが、これは OS によって大きく異なります。Mac OS X では、次の出力を読み取る必要がありますsystemsetup -gettimezone

$ systemsetup -gettimezone
Time Zone: Europe/Copenhagen

Debian および Ubuntu システムでは、以下を読むことができます/etc/timezone

$ cat /etc/timezone
Europe/Oslo

RedHat および direved システムでは、以下から読み取る必要があります/etc/sysconfig/clock

$ grep ZONE /etc/sysconfig/clock
ZONE="Europe/Oslo"
于 2012-11-04T12:30:29.720 に答える
9

この質問を解決するための非常に簡単な方法:

import time

def localTzname():
    offsetHour = time.timezone / 3600
    return 'Etc/GMT%+d' % offsetHour

更新: @MartijnPieters は、「これは DST / サマータイムでは機能しない」と述べました。では、このバージョンはどうでしょうか。

import time

def localTzname():
    if time.daylight:
        offsetHour = time.altzone / 3600
    else:
        offsetHour = time.timezone / 3600
    return 'Etc/GMT%+d' % offsetHour
于 2012-11-04T13:35:07.207 に答える
1

これがあなたにとって役立つかどうかはわかりませんが、より一般的な問題に答えていると思います:

のようなあいまいなタイムゾーンにある日付がある場合CSTsimple-date (python 3.2+ のみ、申し訳ありません) は検索を自動化し、特定の国を優先するなどのことを行うことができます。

例えば:

>>> SimpleDate('2013-07-04 18:53 CST')
Traceback [...
simpledate.AmbiguousTimezone: 3 distinct timezones found: <DstTzInfo 'Australia/Broken_Hill' CST+9:30:00 STD>; <DstTzInfo 'America/Regina' LMT-1 day, 17:01:00 STD>; <DstTzInfo 'Asia/Harbin' LMT+8:27:00 STD> (timezones=('CST',), datetime=datetime.datetime(2013, 7, 4, 18, 53), is_dst=False, country=None, unsafe=False)
>>> SimpleDate('2013-07-04 18:53 CST', country='CN')
SimpleDate('2013-07-04 18:53 CST')
>>> SimpleDate('2013-07-04 18:53 CST', country='CN').utc
SimpleDate('2013-07-04 10:53 UTC', tz='UTC')

国を指定することで、可能な値の範囲を十分に狭め、UTC への変換を可能にする方法に注意してください。

PyTZ でタイムゾーンを検索することで実装されます。

>>> SimpleDate('2013-07-04 18:53 CST', country='CN', debug=True)
...
PyTzFactory: Have country code CN
PyTzFactory: Country code CN has 5 timezones
PyTzFactory: Expanded country codes to 5 timezones
PyTzFactory: Expanding ('CST',)
PyTzFactory: Name lookup failed for CST
PyTzFactory: Found CST using Asia/Shanghai
PyTzFactory: Found CST using Asia/Harbin
PyTzFactory: Found CST using Asia/Chongqing
PyTzFactory: Found CST using Asia/Urumqi
PyTzFactory: Found CST using Asia/Kashgar
PyTzFactory: Expanded timezone to 5 timezones
PyTzFactory: New offset 8:00:00 for Asia/Shanghai
PyTzFactory: Known offset 8:00:00 for Asia/Harbin
PyTzFactory: Known offset 8:00:00 for Asia/Chongqing
PyTzFactory: Known offset 8:00:00 for Asia/Urumqi
PyTzFactory: Known offset 8:00:00 for Asia/Kashgar
PyTzFactory: Have 1 distinct timezone(s)
PyTzFactory: Found Asia/Shanghai
...
SimpleDate('2013-07-04 18:53 CST')

最後に、直接尋ねられた質問に答えるために、ここで別の回答で述べたように、tzlocal もラップするため、タイムゾーンを指定しない場合は自動的に期待どおりに動作します。たとえば、私はチリに住んでいるので、

>>> SimpleDate()
SimpleDate('2013-07-04 19:21:25.757222 CLT', tz='America/Santiago')
>>> SimpleDate().tzinfo
<DstTzInfo 'America/Santiago' CLT-1 day, 20:00:00 STD>

私のロケールのタイムゾーンを提供します(あいまいかどうか)。

于 2013-07-04T23:18:40.553 に答える