문제

내가 지금 제가 생각해 할 수있는 최선은이 괴물입니다.

>>> datetime.utcnow() \
...   .replace(tzinfo=pytz.UTC) \
...   .astimezone(pytz.timezone("Australia/Melbourne")) \
...   .replace(hour=0,minute=0,second=0,microsecond=0) \
...   .astimezone(pytz.UTC) \
...   .replace(tzinfo=None)
datetime.datetime(2008, 12, 16, 13, 0)

즉, 영어로 현재 시간 (UTC)을 가져 와서 다른 시간대로 변환하고 시간을 자정으로 설정 한 다음 UTC로 다시 변환합니다.

나는 사용자의 시간대가 아닌 서버의 시간대를 사용하기 때문에 지금 () 또는 localtime ()을 사용하는 것이 아닙니다.

나는 내가 뭔가를 놓치고 있다고 느끼는 것을 도울 수 없다, 어떤 아이디어가 있습니까?

도움이 되었습니까?

해결책

이렇게하면 몇 가지 방법 호출을 면도 할 수 있다고 생각합니다.

>>> from datetime import datetime
>>> datetime.now(pytz.timezone("Australia/Melbourne")) \
            .replace(hour=0, minute=0, second=0, microsecond=0) \
            .astimezone(pytz.utc)

그러나… 코드에서 미학보다 더 큰 문제가 있습니다. 이는 일광 절약 시간을 오가는 날에 잘못된 결과를 제공합니다.

그 이유는 DateTime 생성자도 replace() DST 변경 사항을 고려하십시오.

예를 들어:

>>> now = datetime(2012, 4, 1, 5, 0, 0, 0, tzinfo=pytz.timezone("Australia/Melbourne"))
>>> print now
2012-04-01 05:00:00+10:00
>>> print now.replace(hour=0)
2012-04-01 00:00:00+10:00 # wrong! midnight was at 2012-04-01 00:00:00+11:00
>>> print datetime(2012, 3, 1, 0, 0, 0, 0, tzinfo=tz)
2012-03-01 00:00:00+10:00 # wrong again!

그러나 문서 tz.localize() 상태 :

이 방법은 tzinfo 인수를 datetime 생성자에게 전달하기보다는 로컬times를 구성하는 데 사용해야합니다.

따라서 문제가 해결됩니다.

>>> import pytz
>>> from datetime import datetime, date, time

>>> tz = pytz.timezone("Australia/Melbourne")
>>> the_date = date(2012, 4, 1) # use date.today() here

>>> midnight_without_tzinfo = datetime.combine(the_date, time())
>>> print midnight_without_tzinfo
2012-04-01 00:00:00

>>> midnight_with_tzinfo = tz.localize(midnight_without_tzinfo)
>>> print midnight_with_tzinfo
2012-04-01 00:00:00+11:00

>>> print midnight_with_tzinfo.astimezone(pytz.utc)
2012-03-31 13:00:00+00:00

그러나 1582 년 이전에는 날짜를 보장하지 않습니다.

다른 팁

@홉의 대답 일광 절약 시간 (DST)에서 전환 당일에 잘못되었습니다. 예를 들어, 2012 년 4 월 1 일. tz.localize() 사용 될수있다:

tz = pytz.timezone("Australia/Melbourne")
today = datetime.now(tz).date()
midnight = tz.localize(datetime.combine(today, time(0, 0)), is_dst=None)
utc_dt = midnight.astimezone(pytz.utc)        

댓글과 마찬가지로 :

#!/usr/bin/env python
from datetime import datetime, time
import pytz # pip instal pytz

tz = pytz.timezone("Australia/Melbourne") # choose timezone

# 1. get correct date for the midnight using given timezone.
today = datetime.now(tz).date()

# 2. get midnight in the correct timezone (taking into account DST)
#NOTE: tzinfo=None and tz.localize()
# assert that there is no dst transition at midnight (`is_dst=None`)
midnight = tz.localize(datetime.combine(today, time(0, 0)), is_dst=None)

# 3. convert to UTC (no need to call `utc.normalize()` due to UTC has no 
#    DST transitions)
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
print midnight.astimezone(pytz.utc).strftime(fmt)

TZ 환경 변수 설정은 시간대 Python의 날짜 및 시간 기능과 함께 작동하는 시간을 수정합니다.

>>> time.gmtime()
(2008, 12, 17, 1, 16, 46, 2, 352, 0)
>>> time.localtime()
(2008, 12, 16, 20, 16, 47, 1, 351, 0)
>>> os.environ['TZ']='Australia/Melbourne'
>>> time.localtime()
(2008, 12, 17, 12, 16, 53, 2, 352, 1)

각 시간대에는 숫자 (예 : US/Central = -6)가 있습니다. 이것은 UTC에서 몇 시간 동안 오프셋으로 정의됩니다. 0000은 자정 이므로이 오프셋을 사용하여 자정 UTC 일 때마다 시간대의 시간을 찾을 수 있습니다. 그것에 접근하기 위해, 나는 당신이 사용할 수 있다고 생각합니다

 time.timezone

에 따르면 파이썬 문서, time.timezone은 실제로이 숫자의 음수 값을 제공합니다.

시간. 타임 존

UTC에서 서쪽으로 몇 초 만에 현지 (DST) 시간대의 상쇄 (대부분의 서유럽에서 부정적인, 미국에서는 긍정적, 영국에서는 0).

따라서 긍정적 인 경우 (예 : 시카고의 자정이라면 (+6 타임 존 값을 가진 경우) 6000 = 6am UTC).

숫자가 음수이면 24에서 빼면 베를린은 -1을 제공하므로 24-1 => 2300 = 11pm을 제공합니다.

이것은 pytz보다 dateutil.tz에서 더 간단합니다.

>>>import datetime
>>>import dateutil.tz
>>>midnight=(datetime.datetime
             .now(dateutil.tz.gettz('Australia/Melbourne'))
             .replace(hour=0, minute=0, second=0, microsecond=0)
             .astimezone(dateutil.tz.tzutc()))
>>>print(midnight)
2019-04-26 14:00:00+00:00

그만큼 Tzinfo 문서 Python 3.6 이후 DateUtil.tz를 권장합니다. dateUtil.tz의 tzinfo 객체는 PYTZ의 로컬 화 기능을 필요로하지 않고 DST와 같은 이상에 아무런 문제가 없습니다. user3850의 예제 사용 :

>>> now = (datetime.datetime(2012, 4, 1, 5,  
...         tzinfo = dateutil.tz.gettz('Australia/Melbourne'))) 
>>> print(now.replace(hour = 0).astimezone(dateutil.tz.tzutc()))
2012-03-31 13:00:00+00:00
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top