我想在VBA中确定不同国家/地区在特定日期的GMT/UTC (包括夏令时)的时间偏差。有什么想法吗?
编辑(来自自答):
谢谢0xA3。我很快地浏览了一下链接页面。我假设你只能得到运行windows的本地的GMT的偏移量:
ConvertLocalToGMT
DaylightTime
GetLocalTimeFromGMT
LocalOffsetFromGMT
SystemTimeToVBTime
LocalOffsetFromGMT在Java中,您可以执行以下操作:
TimeZone bucharestTimeZone = TimeZone.getTimeZone("Europe/Bucharest");
bucharestTimeZone.getOffset(new Date().getTime());
Calendar nowInBucharest = Calendar.getInstance(TimeZone.getTimeZone("Europe/Bucharest"));
nowInBucharest.setTime(new Date());
System.out.println("Bucharest: " + nowInBucharest.get(Calendar.HOUR) + ":" + nowInBucharest.get(Calendar.MINUTE));这意味着我可以得到不同国家(时区)的偏移量,因此我也可以得到实际的时间,比如说在布加勒斯特。我能在VBA中做到这一点吗?
发布于 2014-07-31 00:56:08
请注意解决方案中的小陷阱。
GetTimeZoneInformation()调用返回有关当前时间的DST信息,但转换的日期可能来自具有不同DST设置的时段-因此,转换8月份的1月份日期将应用当前偏差,从而产生的GMT日期比(SystemTimeToTzSpecificLocalTime似乎更适合的正确日期少1小时-尚未测试)
当日期来自另一个年份时也是如此-当DST规则可能不同时。GetTimeZoneInformationForYear应该处理不同年份的变化。一旦完成,我将在这里放一个代码样本。
Windows似乎也没有提供一种可靠的方式来获取时区的3个字母的缩写(Excel 2013支持格式()中的zzz -未经过测试)。
编辑16.04.2015:删除IntArrayToString(),因为它已经存在于下面提到的cpearson.com文章中引用的modWorksheetFunctions.bas中。
添加代码以使用在转换日期时处于活动状态的时区进行转换(在cpearson.com上未解决此问题)。为了简洁起见,没有包含错误处理。
Private Type DYNAMIC_TIME_ZONE_INFORMATION_VB
Bias As Long
StandardName As String
StandardDate As Date
StandardBias As Long
DaylightName As String
DaylightDate As Date
DaylightBias As Long
TimeZoneKeyName As String
DynamicDaylightTimeDisabled As Long
End Type
Private Declare Function GetTimeZoneInformationForYear Lib "kernel32" ( _
wYear As Integer, _
lpDynamicTimeZoneInformation As DYNAMIC_TIME_ZONE_INFORMATION, _
lpTimeZoneInformation As TIME_ZONE_INFORMATION _
) As Long
Private Declare Function GetDynamicTimeZoneInformation Lib "kernel32" ( _
pTimeZoneInformation As DYNAMIC_TIME_ZONE_INFORMATION _
) As Long
Private Declare Function TzSpecificLocalTimeToSystemTimeEx Lib "kernel32" ( _
lpDynamicTimeZoneInformation As DYNAMIC_TIME_ZONE_INFORMATION, _
lpLocalTime As SYSTEMTIME, _
lpUniversalTime As SYSTEMTIME _
) As Long
Function LocalSerialTimeToGmt(lpDateLocal As Date) As Date
Dim retval As Boolean, lpDateGmt As Date, lpSystemTimeLocal As SYSTEMTIME, lpSystemTimeGmt As SYSTEMTIME
Dim lpDTZI As DYNAMIC_TIME_ZONE_INFORMATION
retval = SerialTimeToSystemTime(lpDateLocal, lpSystemTimeLocal)
retval = GetDynamicTimeZoneInformation(lpDTZI)
retval = TzSpecificLocalTimeToSystemTimeEx(lpDTZI, lpSystemTimeLocal, lpSystemTimeGmt)
lpDateGmt = SystemTimeToSerialTime(lpSystemTimeGmt)
LocalSerialTimeToGmt = lpDateGmt
End Function有两种方式可以实现偏移:
对特定年份的offset = (lpDateLocal - lpDateGmt)*24*60
dst = GetTimeZoneInformationForYear(Year(lpDateLocal), lpDTZI, lpTZI) offset = lpTZI.Bias + IIf(lpDateLocal >= SystemTimeToSerialTime(lpTZI.DaylightDate) And lpDateLocal < SystemTimeToSerialTime(lpTZI.StandardDate), lpTZI.DaylightBias, lpTZI.StandardBias)
注意:由于某些原因,此处lpTZI中填充的值不包含年份信息,因此您需要在lpTZI.DaylightDate和lpTZI.StandardDate中设置年份。
https://stackoverflow.com/questions/3120915
复制相似问题