https://timezonedb.com/references/convert-time-zone
提供了一个很好的API,可以获取正确的全球时间、时区和两个位置之间的时区偏移量,考虑到过去/未来的夏令时变化。您建议的只指定时区缩写(例如“将PST转换为EST”)的方法存在问题,因为即使它们不正确,此API也会按照您的时区字面意思进行计算。因此,如果多伦多目前处于
EDT
,但您指定
EST
,您可能会得到错误的时间。使用类似于
(UTC-08:00) Pacific Time (US & Canada)
的“全名”将具有相同的问题。解决这个问题的方法是指定像
America/Vancouver
这样的时区名称(如
此处所列),或者使用适当的参数指定城市、国家和/或地区名称。我编写了一个函数来解决这个问题,但它只适用于某些国家(请参见下文)。
上次万圣节在温哥华时间晚上11:11时,多伦多是什么时间?
http://api.timezonedb.com/v2/convert-time-zone?key=94RKE4SAXH67&from=America/Vancouver&to=America/Toronto&time=1509516660
结果:(默认为XML
,但也可用JSON
。)
<result>
<status>OK</status>
<message/>
<fromZoneName>America/Vancouver</fromZoneName>
<fromAbbreviation>PDT</fromAbbreviation>
<fromTimestamp>1509516660</fromTimestamp>
<toZoneName>America/Toronto</toZoneName>
<toAbbreviation>EDT</toAbbreviation>
<toTimestamp>1509527460</toTimestamp>
<offset>10800</offset>
</result>
程序获取数据:
在决定哪些选项和查询方法时,有很多选择,但这里提供一种使用VBA函数的示例:
圣诞节当天温哥华和柏林之间的时间差是多少?
输入时间: 2018-12-25 00:00:00
= 温哥华本地Unix时间 1545724800
Function GetTimeZoneOffsetHours(fromZone As String, _
toZone As String, UnixTime As Long) As Single
Const key = "94RKE4SAXH67"
Const returnField = "<offset>"
Dim HTML As String, URL As String
Dim XML As String, pStart As Long, pStop As Long
URL = "http://api.timezonedb.com/v2/convert-time-zone?key=" & key & _
"&from=" & fromZone & "&to=" & toZone & "&time=" & UnixTime
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", URL, False
.Send
XML = .ResponseText
End With
pStart = InStr(XML, returnField)
If pStart = 0 Then
MsgBox "Something went wrong!"
Exit Function
End If
pStart = pStart + Len(returnField) + 1
pStop = InStr(pStart, XML, "</") - 1
GetTimeZoneOffsetHours = Val(Mid(XML, pStart, pStop - pStart)) / 60
End Function
Sub testTZ()
Debug.Print "Time Zone Offset (Vancouver to Berlin) = " & _
GetTimeZoneOffsetHours("America/Vancouver", _
"Europe/Berlin", 1545724800) & " hours"
End Sub
Unix/UTC Timestamps:
Unix time is defined as "the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970."
You can convert times between Unix and/or UTC or Local time at: epochconverter.com ... the site also has conversion formulas for several programming languages.
For example, the formua to convert Unix time to GMT/UTC in Excel is:
=(A1 / 86400) + 25569
您也可以下载静态文件(以SQL
或CSV
格式)在此处,而不是调用API,并且该页面还有示例查询。 但是请注意:使用夏令时易犯错误(如上所述)。
我创建了一个虚拟帐户来获取示例中使用的“演示”,但您应该获得自己的(免费)密钥以供长期使用。 (如果由于过度使用而被锁定,我不负责任!)
一个很好的替代时区API是Google Maps时区API。 区别在于您需要指定纬度和经度。似乎没有密钥也能正常工作 您需要注册获取密钥。
在白宫,6月1日的时区偏移量是多少?
https://maps.googleapis.com/maps/api/timezone/json?location=38.8976,-77.0365×tamp=1527811200&key={YourKeyHere}
结果:
{
"dstOffset" : 0,
"rawOffset" : -18000,
"status" : "OK",
"timeZoneId" : "America/Toronto",
"timeZoneName" : "Eastern Standard Time"
}
偏移量将为-18000秒(即5个小时)。
确定夏令时的实施时间
下面是我编写的一个函数,以便我可以“信任”来自不同API的夏令时(DST)值,但是(如其他人所讨论的),规则没有模式而且在世界某些地区甚至在城镇之间也在不断变化,因此这只适用于以下国家:
- DST每年从3月第二个星期日开始
- DST每年从11月第一个星期日结束
适用的国家有巴哈马,百慕大,加拿大,古巴,海地,圣皮埃尔和美国。(来源:各国夏令时**)
Function IsDST(dateTime As Date) As Boolean
'Returns TRUE if Daylight Savings is in effect during the [dateTime]
'DST Start (adjust clocks forward) Second Sunday March at 02:00am
'DST end (adjust clocks backward) First Sunday November at 02:00am
Dim DSTStart As Date, DSTstop As Date
DSTStart = DateSerial(Year(dateTime), 3, _
(14 - Weekday(DateSerial(Year(dateTime), 3, 1), 3))) + (2 / 24)
DSTstop = DateSerial(Year(dateTime), 11, _
(7 - Weekday(DateSerial(Year(dateTime), 11, 1), 3))) + (2 / 24)
IsDST = (dateTime >= DSTStart) And (dateTime < DSTstop)
End Function
以下是我如何使用 IsDST
函数的几个示例:
Public Function UTCtoPST(utcDateTime As Date) As Date
'Example for 'PST' time zone, where Offset = -7 during DST, otherwise if -8
If IsDST(utcDateTime) Then
UTCtoPST = utcDateTime - (7 / 24)
Else
UTCtoPST = utcDateTime - (8 / 24)
End If
End Function
Function UTCtimestampMStoPST(ByVal ts As String) As Date
'Example for 'PST', to convert a UTC Unix Time Stamp to 'PST' Time Zone
UTCtimestampMStoPST = UTCtoPST((CLng(Left(ts, 10)) / 86400) + 25569)
End Function
注意函数
IsDST
是不完整的:它没有考虑到在2点实际生效之前/之后的小时数。具体来说,在春季,时钟从标准时间
01:59
的
最后一刻向前跳动到
03:00
的夏令时,并且
那天有23个小时,而在秋季,时钟从夏令时
01:59
的
最后一刻向后跳动到标准时间
01:00
,重复那个小时,并且
那天有25个小时......
但是,如果有人想要添加该功能以更新该函数,请随意!我对那最后一部分感到困惑,而且并不需要那么详细的信息,但我相信其他人会感激的!
最后一个选择是我用于轮询当前/未来/历史
天气数据的API,同时也提供
时区偏移量,它是DarkSky。
它通过纬度/经度查询,是免费的(每日最多1000次调用),并提供
"超精确的天气数据"(在美国更为如此,因为它可以预测到
分钟和
平方码的天气!但我在不可预测的加拿大西海岸也看到了相当准确的预测!)
响应仅以JSON格式提供,最后一行是
时区偏移与UTC/GMT时间。
DarkSky示例调用:
https://api.darksky.net/forecast/85b57f827eb89bf903b3a796ef53733c/40.70893,-74.00662
它说接下来的60个小时Stack Overflow总部会下雨。☂
...但是我不知道,今天看起来是个很好的日子!☀
(flag)