[英]How to compute the time difference between two time zones in python?
如何計算 Python 中兩個時區之間的時差? 也就是說,我不想比較 TZ-aware datetime
對象並獲得timedelta
; 我想比較兩個TimeZone
對象並獲得一個offset_hours
。 datetime
庫中沒有任何內容可以處理此問題, pytz
也沒有。
您必須知道的第一件事是,兩個時區之間的偏移量不僅取決於相關時區,還取決於您詢問的日期。 例如,夏令時開始和結束的日期在 2007 年在美國發生了變化。雖然基本的時區物流在任何一個地方都很少發生變化,但全球的變化率卻不容忽視。 因此,您必須將相關日期合並到您的函數中。
完成必要的前言后,如果您利用鍾擺庫,實際功能並不太難編寫。 它應該是這樣的:
import pendulum
def tz_diff(home, away, on=None):
"""
Return the difference in hours between the away time zone and home.
`home` and `away` may be any values which pendulum parses as timezones.
However, recommended use is to specify the full formal name.
See https://gist.github.com/pamelafox/986163
As not all time zones are separated by an integer number of hours, this
function returns a float.
As time zones are political entities, their definitions can change over time.
This is complicated by the fact that daylight savings time does not start
and end on the same days uniformly across the globe. This means that there are
certain days of the year when the returned value between `Europe/Berlin` and
`America/New_York` is _not_ `6.0`.
By default, this function always assumes that you want the current
definition. If you prefer to specify, set `on` to the date of your choice.
It should be a `Pendulum` object.
This function returns the number of hours which must be added to the home time
in order to get the away time. For example,
```python
>>> tz_diff('Europe/Berlin', 'America/New_York')
-6.0
>>> tz_diff('Europe/Berlin', 'Asia/Kabul')
2.5
```
"""
if on is None:
on = pendulum.today()
diff = (on.timezone_(home) - on.timezone_(away)).total_hours()
# what about the diff from Tokyo to Honolulu? Right now the result is -19.0
# it should be 5.0; Honolulu is naturally east of Tokyo, just not so around
# the date line
if abs(diff) > 12.0:
if diff < 0.0:
diff += 24.0
else:
diff -= 24.0
return diff
正如文檔中所述,當您掃過一年中的幾天時,您可能無法在任何兩個給定位置之間獲得穩定的結果。 但是,實現一個選擇當前年份天數的中值結果的變體是留給讀者的練習。
這是一個使用 Python 庫 Pytz 的解決方案,它解決了夏令時結束時時間不明確的問題。
from pytz import timezone
import pandas as pd
def tz_diff(date, tz1, tz2):
'''
Returns the difference in hours between timezone1 and timezone2
for a given date.
'''
date = pd.to_datetime(date)
return (tz1.localize(date) -
tz2.localize(date).astimezone(tz1))\
.seconds/3600
下面的示例分別計算 UTC 和澳大利亞時間在 1 月 1 日和 6 月 1 日之間的時差。 請注意如何考慮夏令時。
utc = timezone('UTC')
aus = timezone('Australia/Sydney')
tz_diff('2017-01-01', utc, aus)
# 11.0
tz_diff('2017-06-01', utc, aus)
# 10.0
謝謝
這是另一個解決方案:
from datetime import datetime
from pytz import timezone
from dateutil.relativedelta import relativedelta
utcnow = timezone('utc').localize(datetime.utcnow()) # generic time
here = utcnow.astimezone(timezone('US/Eastern')).replace(tzinfo=None)
there = utcnow.astimezone(timezone('Asia/Ho_Chi_Minh')).replace(tzinfo=None)
offset = relativedelta(here, there)
offset.hours
這里我們要做的是將時間轉換為兩個不同的時區。 然后,我們刪除了時區信息,這樣當您使用relativedelta 計算兩者之間的差異時,我們會欺騙它認為這是兩個不同的時刻,而不是不同時區的同一時刻。
上述結果將返回 -11,但由於美國/東部遵守夏令時而亞洲/Ho_Chi_Minh 不遵守,因此該金額全年可能會發生變化。
這是一個代碼片段,用於獲取 UTC 和美國/東部之間的差異,但它應該適用於任何兩個時區。
# The following algorithm will work no matter what is the local timezone of the server,
# but for the purposes of this discussion, let's assume that the local timezone is UTC.
local_timestamp = datetime.now()
# Assume that utc_timestamp == 2019-01-01 12:00.
utc_timestamp = pytz.utc.localize(local_timestamp)
# If it was 12:00 in New York, it would be 20:00 in UTC. So us_eastern_timestamp is a UTC
# timestamp with the value of 2019-01-01 20:00.
us_eastern_timestamp = timezone("US/Eastern").localize(local_timestamp).astimezone(pytz.utc)
# delta is a Python timedelta object representing the interval between the two timestamps,
# which, in our example, is -8 hours.
delta = utc_timestamp - us_eastern_timestamp
# In the last line, we convert the timedelta into an integer representing the number of
# hours.
print round(delta.total_seconds() / 60.0 / 60.0)
(tz_from.localize(date) - tz_to.localize(date)).seconds/3600.0
其中 tz_from 和 tz_to 是開始和結束時區。 您必須指定特定日期。
我創建了兩個函數來處理時區。
import datetime
import pytz
def diff_hours_tz(from_tz_name, to_tz_name, negative=False):
"""
Returns difference hours between timezones
res = diff_hours_tz("UTC", "Europe/Paris") : 2
"""
from_tz = pytz.timezone(from_tz_name)
to_tz = pytz.timezone(to_tz_name)
utc_dt = datetime.datetime.now(datetime.timezone.utc)
dt_from = dt_to = datetime.datetime.utcnow()
dt_from = from_tz.localize(dt_from)
dt_to = to_tz.localize(dt_to)
from_d = dt_from - utc_dt
if from_d.days < 0:
return diff_hours_tz(to_tz_name, from_tz_name, True)
dt_delta = dt_from - dt_to
negative_int = -1 if negative else 1
return int(dt_delta.seconds/3600)*negative_int
def dt_tz_to_tz(dt, from_tz_name, to_tz_name):
"""
Apply difference hours between timezones to a datetime object
dt_new = dt_tz_to_tz(datetime.datetime.now(), "UTC", "Europe/Paris")
"""
hours = diff_hours_tz(from_tz_name, to_tz_name)
return dt+datetime.timedelta(hours=hours)
# Usage example
res = diff_hours_tz("Europe/Paris", "America/New_York")
# Result : -6
res = diff_hours_tz("UTC", "Europe/Paris")
# Result : 2
now = datetime.datetime.now()
# Result : 2019-06-18 15:10:31.720105
dt_new = dt_tz_to_tz(now, "UTC", "Europe/Paris")
# Result : 2019-06-18 17:10:31.720105
dt_new = dt_tz_to_tz(now, "Europe/Paris", "America/New_York")
# Result : 2019-06-18 09:10:31.720105
dt_new = dt_tz_to_tz(now, "America/New_York", "Europe/Paris")
# Result : 2019-06-18 21:10:31.720105
我希望它會有所幫助!
from datetime import datetime
from zoneinfo import ZoneInfo
dt = datetime.now() # 2020-09-13
tz0, tz1 = "Europe/Berlin", "US/Eastern" # +2 vs. -4 hours rel. to UTC
utcoff0, utcoff1 = dt.astimezone(ZoneInfo(tz0)).utcoffset(), dt.astimezone(ZoneInfo(tz1)).utcoffset()
print(f"hours offset between {tz0} -> {tz1} timezones: {(utcoff1-utcoff0).total_seconds()/3600}")
>>> hours offset between Europe/Berlin -> US/Eastern timezones: -6.0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.