I have an MS Access app which is used in two different time zones. The difference is 7 hours. I needed to find a time when the both of the offices are off so I can close their database and I can do compact and repair and do backup of them.
So I will not need to create two separates front end and I tell close database one at 1000 PM and another in 4 AM I figure out I can say Close database at 00:30 AM UTC. But I do not know how to convert the same one in Local. Right now my code for closing the database looks like this:
Private Sub Form_Timer()
Dim RunAtLocalTime As String
RunAtLocalTime = Format(Now(), "HH:MM:SS")
If RunAtLocalTime = ("00:00:00") Then
DoCmd.Quit
End If
End Sub
And I want to do something like this:
Private Sub Form_Timer()
Dim RunAtLocalTime As String
Dim UTCTIME As
'''RunAtLocalTime = Convert(UTCTIME)
RunAtLocalTime = Format(Now(), "HH:MM:SS")
If RunAtLocalTime = ("00:00:00") Then
DoCmd.Quit
End If
End Sub
I have found the following functions:
This one returns the UTC timezone offset:
Option Compare Database
Option Explicit
Private Declare Function GetTimeZoneInformation Lib "kernel32" (lpTimeZoneInformation As TimeZoneInfo) As Long
Private Type SystemTime
intYear As Integer
intMonth As Integer
intwDayOfWeek As Integer
intDay As Integer
intHour As Integer
intMinute As Integer
intSecond As Integer
intMilliseconds As Integer
End Type
Private Type TimeZoneInfo
lngBias As Long
intStandardName(32) As Integer
intStandardDate As SystemTime
intStandardBias As Long
intDaylightName(32) As Integer
intDaylightDate As SystemTime
intDaylightBias As Long
End Type
Public Function GetUTCOffset() As Date
Dim lngRet As Long
Dim udtTZI As TimeZoneInfo
lngRet = GetTimeZoneInformation(udtTZI)
GetUTCOffset = udtTZI.lngBias / 60 / 24
End Function
source: [this site] (edit link no longer valid, removed)
And this one that converts a time to GMT:
Option Explicit
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Private Type TIME_ZONE_INFORMATION
Bias As Long
StandardName(31) As Integer
StandardDate As SYSTEMTIME
StandardBias As Long
DaylightName(31) As Integer
DaylightDate As SYSTEMTIME
DaylightBias As Long
End Type
Private Declare Function GetTimeZoneInformation Lib "kernel32" (lpTimeZoneInformation As TIME_ZONE_INFORMATION) As Long
'Purpose : Converts local time to GMT.
'Inputs : dtLocalDate The local data time to return as GMT.
'Outputs : Returns the local time in GMT.
'Author : Andrew Baker
'Date : 13/11/2002 10:16
'Notes :
'Revisions :
Public Function ConvertLocalToGMT(dtLocalDate As Date) As Date
Dim lSecsDiff As Long
'Get the GMT time diff
lSecsDiff = GetLocalToGMTDifference()
'Return the time in GMT
ConvertLocalToGMT = DateAdd("s", -lSecsDiff, dtLocalDate)
End Function
'Purpose : Converts GMT time to local time.
'Inputs : dtLocalDate The GMT data time to return as local time.
'Outputs : Returns GMT as local time.
'Author : Andrew Baker
'Date : 13/11/2002 10:16
'Notes :
'Revisions :
Public Function ConvertGMTToLocal(gmtTime As Date) As Date
Dim Differerence As Long
Differerence = GetLocalToGMTDifference()
ConvertGMTToLocal = DateAdd("s", Differerence, gmtTime)
End Function
'Purpose : Returns the time lDiff between local and GMT (secs).
'Inputs : dtLocalDate The local data time to return as GMT.
'Outputs : Returns the local time in GMT.
'Author : Andrew Baker
'Date : 13/11/2002 10:16
'Notes : A positive number indicates your ahead of GMT.
'Revisions :
Public Function GetLocalToGMTDifference() As Long
Const TIME_ZONE_ID_INVALID& = &HFFFFFFFF
Const TIME_ZONE_ID_STANDARD& = 1
Const TIME_ZONE_ID_UNKNOWN& = 0
Const TIME_ZONE_ID_DAYLIGHT& = 2
Dim tTimeZoneInf As TIME_ZONE_INFORMATION
Dim lRet As Long
Dim lDiff As Long
'Get time zone info
lRet = GetTimeZoneInformation(tTimeZoneInf)
'Convert diff to secs
lDiff = -tTimeZoneInf.Bias * 60
GetLocalToGMTDifference = lDiff
'Check if we are in daylight saving time.
If lRet = TIME_ZONE_ID_DAYLIGHT& Then
'In daylight savings, apply the bias
If tTimeZoneInf.DaylightDate.wMonth <> 0 Then
'if tTimeZoneInf.DaylightDate.wMonth = 0 then the daylight
'saving time change doesn't occur
GetLocalToGMTDifference = lDiff - tTimeZoneInf.DaylightBias * 60
End If
End If
End Function
source : this site
The second one I believe uses the first one as well.
Either will suit your needs I believe.
Be wary of which method you use for time zone conversion, including to/from the UTC standard. The rules for time zones (including differences in daylight savings) are confusing to start with, since they vary not only by region or country, but in some cases by state or county.
To further confuse matters, the rules are constantly evolving, so for logical reasons (like the remaining half the planet, hopefully, moving towards eliminating Daylight Savings), and sometimes not so logical (country leaders changing rules on a whim), and other times improperly communicated (case study: Turkey's 2015 Chaos).
Even Canada/USA had a major change in 2007 that coders are often forgetting to account for. Other solutions on this site (or this page!) miscalculate is certain situations or timeframes.
Ideally, we'd all get out information from the same place, using the same methods. The authority on future and historical time zone information is considered to be the tz database and related code published by iana.org
This following conversion method accounts for all Daylight Savings and Time Zone differences, which I diligently confirmed with lengthy analysis and through authoritative documents such as Unicode's Common Locale Data Repository.
I minimized for space and efficiency and included only functions relevant to my purposes: conversion between UTC time and local time, and between Epoch† Timestamp and local time. This is an adaptation of code from Tim Hall.
†Epoch Timestamp, also known an Unix time is the number of seconds since January 1, 1970, and is used as a standard time format in many API's and other programming resources. More info at epochconverter.com, and Wikipedia.
I'd suggest that this be placed in a module by itself.
Option Explicit
'UTC/Local Time Conversion
'Adapted from code by Tim Hall published at https://github.com/VBA-tools/VBA-UtcConverter
'PUBLIC FUNCTIONS:
' - UTCtoLocal(utc_UtcDate As Date) As Date converts UTC datetimes to local
' - LocalToUTC(utc_LocalDate As Date) As Date converts local DateTime to UTC
' - TimestampToLocal(st As String) As Date converts epoch timestamp to Local Time
' - LocalToTimestamp(dt as date) as String converts Local Time to timestamp
'Accuracy confirmed for several variations of time zones & DST rules. (ashleedawg)
'===============================================================================
Private Type utc_SYSTEMTIME
utc_wYear As Integer: utc_wMonth As Integer: utc_wDayOfWeek As Integer: utc_wDay As Integer
utc_wHour As Integer: utc_wMinute As Integer: utc_wSecond As Integer: utc_wMilliseconds As Integer
End Type
Private Type utc_TIME_ZONE_INFORMATION
utc_Bias As Long: utc_StandardName(0 To 31) As Integer: utc_StandardDate As utc_SYSTEMTIME: utc_StandardBias As Long
utc_DaylightName(0 To 31) As Integer: utc_DaylightDate As utc_SYSTEMTIME: utc_DaylightBias As Long
End Type
'http://msdn.microsoft.com/library/windows/desktop/ms724421.aspx /ms724949.aspx /ms725485.aspx
Private Declare PtrSafe Function utc_GetTimeZoneInformation Lib "kernel32" Alias "GetTimeZoneInformation" _
(utc_lpTimeZoneInformation As utc_TIME_ZONE_INFORMATION) As Long
Private Declare PtrSafe Function utc_SystemTimeToTzSpecificLocalTime Lib "kernel32" Alias "SystemTimeToTzSpecificLocalTime" _
(utc_lpTimeZoneInformation As utc_TIME_ZONE_INFORMATION, utc_lpUniversalTime As utc_SYSTEMTIME, utc_lpLocalTime As utc_SYSTEMTIME) As Long
Private Declare PtrSafe Function utc_TzSpecificLocalTimeToSystemTime Lib "kernel32" Alias "TzSpecificLocalTimeToSystemTime" _
(utc_lpTimeZoneInformation As utc_TIME_ZONE_INFORMATION, utc_lpLocalTime As utc_SYSTEMTIME, utc_lpUniversalTime As utc_SYSTEMTIME) As Long
Private Function utc_DateToSystemTime(utc_Value As Date) As utc_SYSTEMTIME ' "Helper Function" for Public subs (below)
With utc_DateToSystemTime
.utc_wYear = Year(utc_Value): .utc_wMonth = Month(utc_Value): .utc_wDay = Day(utc_Value)
.utc_wHour = Hour(utc_Value): .utc_wMinute = Minute(utc_Value): .utc_wSecond = Second(utc_Value): .utc_wMilliseconds = 0
End With
End Function
Private Function utc_SystemTimeToDate(utc_Value As utc_SYSTEMTIME) As Date ' "Helper Function" for Public Functions (below)
utc_SystemTimeToDate = DateSerial(utc_Value.utc_wYear, utc_Value.utc_wMonth, utc_Value.utc_wDay) + _
TimeSerial(utc_Value.utc_wHour, utc_Value.utc_wMinute, utc_Value.utc_wSecond)
End Function
'===============================================================================
Public Function TimestampToLocal(st As String) As Date
TimestampToLocal = UTCtoLocal((Val(st) / 86400) + 25569)
End Function
Public Function LocalToTimestamp(dt As Date) As String
LocalToTimestamp = (LocalToUTC(dt) - 25569) * 86400
End Function
Public Function UTCtoLocal(utc_UtcDate As Date) As Date
On Error GoTo errorUTC
Dim utc_TimeZoneInfo As utc_TIME_ZONE_INFORMATION, utc_LocalDate As utc_SYSTEMTIME
utc_GetTimeZoneInformation utc_TimeZoneInfo
utc_SystemTimeToTzSpecificLocalTime utc_TimeZoneInfo, utc_DateToSystemTime(utc_UtcDate), utc_LocalDate
UTCtoLocal = utc_SystemTimeToDate(utc_LocalDate)
Exit Function
errorUTC:
Debug.Print "UTC parsing error: " & Err.Number & " - " & Err.Description: Stop
End Function
Public Function LocalToUTC(utc_LocalDate As Date) As Date
On Error GoTo errorUTC
Dim utc_TimeZoneInfo As utc_TIME_ZONE_INFORMATION, utc_UtcDate As utc_SYSTEMTIME
utc_GetTimeZoneInformation utc_TimeZoneInfo
utc_TzSpecificLocalTimeToSystemTime utc_TimeZoneInfo, utc_DateToSystemTime(utc_LocalDate), utc_UtcDate
LocalToUTC = utc_SystemTimeToDate(utc_UtcDate)
Exit Function
errorUTC:
Debug.Print "UTC conversion error: " & Err.Number & " - " & Err.Description: Stop
End Function
I know this seems like an awful lot of code just to add/subtract a few hours from a time, but I painstakingly researched, hoping to find a reliable shorter/easier method that's guaranteed to be accurate with both current and historical times, but was unsuccessful. All that's needed to use this method is a copy & paste. ☺
Sub testTZC()
'(Note that "Local time" in these examples is Vancouver/Los Angeles)
MsgBox LocalToUTC("2004-04-04 01:00") 'returns: 2004-04-04 9:00:00 AM (not DST)
MsgBox LocalToUTC("2004-04-04 03:00") 'returns: 2004-04-04 10:00:00 AM (is DST)
MsgBox UTCtoLocal("2000-01-01 00:00") 'returns: 1999-12-31 4:00:00 PM
MsgBox TimestampToLocal("1234567890") 'returns: 2009-02-13 3:31:30 PM
MsgBox LocalToTimestamp("April 17, 2019 7:45:55 PM") 'returns: 1555555555
End Sub
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With