programing

Python: 현지 시간대 파악

yellowcard 2023. 8. 28. 20:57
반응형

Python: 현지 시간대 파악

로그 파일의 UTC 타임스탬프를 로컬 타임스탬프와 비교하고 싶습니다. 로을생때할성을 할 때datetime객체, 저는 다음과 같은 것을 사용합니다.

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

나는 그것을 대체할 자동 도구를 찾고 싶습니다.tzinfo=pytz.timezone('Israel')현재 현지 표준 시간대를 사용합니다.

아이디어 있어요?

Python 3.x에서 로컬 시간대는 다음과 같이 파악할 수 있습니다.

>>> import datetime
>>> print(datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo)
AEST

의 교묘한 용법입니다.datetime의 코드.

python < 3.6의 경우 필요합니다.

>>> import datetime
>>> print(datetime.datetime.now(datetime.timezone(datetime.timedelta(0))).astimezone().tzinfo)
AEST

필요한 작업을 수행하는 tzlocal 유형의 dateutil을 사용해 보십시오.

로그 파일의 UTC 타임스탬프를 로컬 타임스탬프와 비교합니다.

휴대용으로는 현지 시간대의 올슨 TZ 이름을 찾기가 어렵습니다.다행히도 비교를 수행하는 데 필요하지 않습니다.

tzlocal module은 로컬 시간대에 해당하는 피츠 시간대를 반환합니다.

from datetime import datetime

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

tz = get_localzone()
local_dt = tz.localize(datetime(2010, 4, 27, 12, 0, 0, 0), is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc) #NOTE: utc.normalize() is unnecessary here

지금까지 제시된 다른 솔루션과 달리 위의 코드는 다음과 같은 문제를 방지합니다.

  • 현지 시간은 모호할있습니다. 즉, 일부 현지 시간에서는 정확한 비교가 불가능할 수 있습니다.
  • 은 과거한 현지 에 대해 수 . 시간 인식 시간 /객체지를일는라리러이브부하원식짜예▁(시▁that(▁some리:러etime라브▁time이▁supportzonee▁libraries일-)를 지원하는 일부 라이브러리:dateutil하지 않음) 그것을고않습니다지하려▁)다니않습.

참고: 단순한 datetime 개체에서 시간대 인식 datetime 개체를 가져오려면 다음을 사용해야 합니다*.

local_dt = tz.localize(datetime(2010, 4, 27, 12, 0, 0, 0), is_dst=None)

다음 대신:

#XXX fails for some timezones
local_dt = datetime(2010, 4, 27, 12, 0, 0, 0, tzinfo=tz)

*is_dst=None지정된 로컬 시간이 모호하거나 존재하지 않는 경우에는 예외를 적용합니다.

모든 로컬 타임스탬프가 로컬 시간대에 대해 동일한 (현재) UTC 오프셋을 사용하는 것이 확실한 경우 stdlib만 사용하여 비교를 수행할 수 있습니다.

# convert a naive datetime object that represents time in local timezone to epoch time
timestamp1 = (datetime(2010, 4, 27, 12, 0, 0, 0) - datetime.fromtimestamp(0)).total_seconds()

# convert a naive datetime object that represents time in UTC to epoch time
timestamp2 = (datetime(2010, 4, 27, 9, 0) - datetime.utcfromtimestamp(0)).total_seconds()

timestamp1그리고.timestamp2직접 비교할 수 있습니다.

참고:

  • timestamp1(에포크)에서 합니다.datetime.fromtimestamp(0)는 지금과 ).
  • fromtimestamp()를 생성합니다. 즉, nevery datetime 개체를 생성합니다.
  • utcfromtimestamp()UTC에서 순진한 날짜/시간 개체를 만듭니다.

저도 같은 질문을 하고 있었는데 1번에서 답을 찾았습니다.

섹션 8.1.7: "%z" 형식(낮은 경우, Z 대문자는 시간대도 반환하지만 4자리 형식은 반환하지 않지만 [3]과 같은 시간대 약어 형식)의 strftime은 이메일 헤더에 표준인 "+/- 4DIGIT" 형식을 반환합니다(RFC 2822의 섹션 3.3 참조, [2],이는 전자 메일 헤더의 시간대를 지정하는 다른 방법을 폐지합니다.

따라서 표준 시간대를 이 형식으로 지정하려면 다음을 사용합니다.

time.strftime("%z")

[1] http://docs.python.org/2/library/datetime.html

[2] https://www.rfc-editor.org/rfc/rfc2822#section-3.3

표준 시간대 약어: http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations , 참조용으로만 제공됩니다.

다음은 표준 립을 사용하는 3.7+에서 작동하는 것으로 나타납니다.

from datetime import timedelta
from datetime import timezone
import time

def currenttz():
    if time.daylight:
        return timezone(timedelta(seconds=-time.altzone),time.tzname[1])
    else:
        return timezone(timedelta(seconds=-time.timezone),time.tzname[0])

먼저 pytz 및 tz 로컬 모듈을 가져옵니다.

pip install pytz tzlocal

그리고나서

from tzlocal import get_localzone
local = get_localzone()

그러면 당신은 다음과 같은 것들을 할 수 있습니다.

from datetime import datetime
print(datetime.now(local))

표준 라이브러리만 사용하여 로컬 표준 시간대를 얻는 방법은 다음과 같습니다(*nix 환경에서만 작동).

>>> '/'.join(os.path.realpath('/etc/localtime').split('/')[-2:])
'Australia/Sydney'

이를 사용하여 다음을 생성할 수 있습니다.pytz표준 시간대:

>>> import pytz
>>> my_tz_name = '/'.join(os.path.realpath('/etc/localtime').split('/')[-2:])
>>> my_tz = pytz.timezone(my_tz_name)
>>> my_tz
<DstTzInfo 'Australia/Sydney' LMT+10:05:00 STD>

다음 를 ...에 적용할 수 그런 다음 이를 응용할 수 있습니다.datetime:

>>> import datetime
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2014, 9, 3, 9, 23, 24, 139059)

>>> now.replace(tzinfo=my_tz)
>>> now
datetime.datetime(2014, 9, 3, 9, 23, 24, 139059, tzinfo=<DstTzInfo 'Australia/Sydney' LMT+10:05:00 STD>)

다음은 @vbem의 솔루션에 대한 약간 더 간결한 버전입니다.

from datetime import datetime as dt

dt.utcnow().astimezone().tzinfo

유일한 실질적인 차이점은 내가 교체했다는 것입니다.datetime.datetime.now(datetime.timezone.utc)와 함께datetime.datetime.utcnow()간략하게 설명하자면, 저는 또한 에일리어스를 사용했습니다.datetime.datetime~하듯이dt.

저는 UTC 오프셋(초)을 원합니다.이것은 다음과 같습니다.

dt.utcnow().astimezone().utcoffset().total_seconds()

이스라엘 현지 표준 시간대의 ISO 표현을 포함하는 ISO 형식 문자열을 만들려면 다음과 같이 하십시오.+04:00) :

이스라엘의 서버에서:

>>> datetime.now(datetime.now().astimezone().tzinfo).isoformat()
'2021-09-07T01:02.030042+04:00'

이렇게 하면 UTC 또는 현지 시간의 다른 날짜/시간 객체와 적절하게 비교되는 "시간대 인식" 날짜 객체가 생성됩니다.그러나 시간대 ISO 표현(및 날짜/시간 문자열 자체)은 다음과 같이 샌프란시스코의 서버에서 동일한 시간에 실행하면 변경됩니다.

미국 캘리포니아주 샌프란시스코(태평양)에 있는 서버:

>>> datetime.now(datetime.now().astimezone().tzinfo).isoformat()
'2021-09-06T14:01:02.030042-07:00'

datetime두 경우 모두 개체가 서로 호환됩니다.을 빼면 시간 델타가 0

Python3의 모든 서버에 있습니다.6+:

>>> (datetime.fromisoformat('2021-09-06T14:01:02.030042-07:00') -
...  datetime.fromisoformat('2021-09-07T01:01:02.030042+04:00'))
datetime.timedelta(0)

비표준 모듈 방지(날짜 시간 모듈의 누락된 방법인 것으로 보임):

from datetime import datetime
utcOffset_min = int(round((datetime.now() - datetime.utcnow()).total_seconds())) / 60   # round for taking time twice
utcOffset_h = utcOffset_min / 60
assert(utcOffset_min == utcOffset_h * 60)   # we do not handle 1/2 h timezone offsets

print 'Local time offset is %i h to UTC.' % (utcOffset_h)

위의 Thoku의 답변을 바탕으로 다음은 시간대를 가장 가까운 30분으로 해결하는 답변입니다(일부 시간대(예: 사우스오스트레일리아 주).

from datetime import datetime
round((round((datetime.now()-datetime.utcnow()).total_seconds())/1800)/2)

J. F. Sebastian의 답변에 따르면 표준 라이브러리를 사용하여 다음 작업을 수행할 수 있습니다.

import time, datetime
local_timezone = datetime.timezone(datetime.timedelta(seconds=-time.timezone))

3.4에서 테스트되었으며, 3.4+에서 작동해야 합니다.

당신은 진자에 만족할지도 모릅니다.

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

Pendu는 날짜를 조작하기 위해 잘 설계된 API를 가지고 있습니다.모든 것이 TZ 인식입니다.

또한 로컬 호스트 구성을 읽고 이를 기반으로 시간대 인식 local_time을 얻는 간단한 방법을 찾고 있습니다.python 3.6+ 기준으로 가장 간단한 접근법은 다음과 같은 dateutil.tz 을 사용하는 것입니다./etc/localtime시간대를 인식하는 날짜/시간 개체를 얻는 데 도움이 됩니다.

자세한 내용은 https://dateutil.readthedocs.io/en/stable/tz.html 에서 확인할 수 있습니다.

원하는 것을 달성하기 위한 구현은 다음과 같습니다.

from datetime import datetime
from dateutil import tz
local_time = datetime.now(tz.gettz())

그러면 다음 local_time이 제공됩니다.

2019-10-18 13:41:06.624536-05:00

이 주제를 조사하는 데 사용한 추가 자료: Paul Gansle 시간대에 대한 프레젠테이션: https://www.youtube.com/watch?v=l4UCKCo9FWY

피츠: 서부에서 가장 빠른 풋건 https://blog.ganssle.io/articles/2018/03/pytz-fastest-footgun.html

로그 파일의 UTC 타임스탬프를 로컬 타임스탬프와 비교하려고 합니다.

이것이 당신의 의도라면, 저는 특정 tzinfo 매개변수나 추가 외부 라이브러리를 지정하는 것에 대해 걱정하지 않을 것입니다.Python 3.5 이후에는 UTC와 로컬 타임스탬프를 자동으로 생성하는 데 필요한 모든 것이 내장된 datetime 모듈입니다.

import datetime
f = "%a %b %d %H:%M:%S %Z %Y"         # Full format with timezone

# tzinfo=None
cdatetime = datetime.datetime(2010, 4, 27, 12, 0, 0, 0)  # 1. Your example from log
cdatetime = datetime.datetime.now()   # 2. Basic date creation (default: local time)
print(cdatetime.strftime(f))          # no timezone printed
# Tue Apr 27 12:00:00  2010

utctimestamp = cdatetime.astimezone(tz=datetime.timezone.utc)  # 1. convert to UTC
utctimestamp = datetime.datetime.now(tz=datetime.timezone.utc) # 2. create in UTC
print(utctimestamp.strftime(f))
# Tue Apr 27 17:00:00 UTC 2010

localtimestamp = cdatetime.astimezone()               # 1. convert to local [default]
localtimestamp = datetime.datetime.now().astimezone()  # 2. create with local timezone
print(localtimestamp.strftime(f))
# Tue Apr 27 12:00:00 CDT 2010

datetime.strftime()의 '%Z' 매개 변수는 시간대 약어를 사람이 읽을 수 있는 타임스탬프에 인쇄합니다.

간단한 것들의 경우, 다음과 같습니다.tzinfoOS에 시간대 오프셋을 쿼리하는 구현을 사용할 수 있습니다.

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())

tzlocal from 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'
>>> 

먼저, 이 질문은 인식된 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

이제 새로운 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'
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)

이것이 당신에게 도움이 되기를 바랍니다.

언급URL : https://stackoverflow.com/questions/2720319/python-figure-out-local-timezone

반응형