Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

UTC time in vfp

Status
Not open for further replies.

avsalf

Programmer
Oct 19, 2009
18
CO
This function is beatiful from Rick Strahl
Representing dates and times across timezones can be a challenge especially if you don’t lay out a plan up front on how to store dates consistently. The sneaky thing with date time management in larger applications and especially applications that live on the Web or are shared across locations, is that problems don’t usually show up until much later in the lifetime of the application. For FoxPro in particular it’s not natural to store dates in anything but local machine format as the language doesn’t support direct UTC formats so it’s very common to see FoxPro applications use local dates which is usually a bad idea.

Here’s why and how we can address these issues


*** Code exists also in wwAPI of any West Wind Tools!
*** SET PROCEDURE TO wwAPI Additive
#define Testing .t.

SET PROCEDURE TO TimeZone additive

#IF Testing

? "Timezone: " + TRANSFORM(GetTimeZone()) + " minutes"
ltTime = DATETIME()
? "Current Time: ", ltTime

ltUtc = GetUtcTime(ltTime)
? "UTC Time: ", ltUtc

ltTime = FromUtcTime(ltUtc)
? "Back to local: ", ltTime
#ENDIF


************************************************************************
* GetUtcTime
****************************************
*** Function: Returns UTC time from local time
*** Assume:
*** Pass:
*** Return:
************************************************************************
FUNCTION GetUtcTime(ltTime)

IF EMPTY(ltTime)
ltTime = DATETIME()
ENDIF

*** Adjust the timezone offset
RETURN ltTime + (GetTimeZone() * 60)
ENDFUNC
* GetUtcTime

************************************************************************
* FromUtcTime
****************************************
*** Function: Returns local time from UTC Time
*** Assume:
*** Pass:
*** Return:
************************************************************************
FUNCTION FromUtcTime(ltTime)
RETURN ltTime - (GetTimeZone() * 60)
ENDFUNC
* FromUtcTime

************************************************************************
FUNCTION GetTimeZone
*********************************
*** Function: Returns the TimeZone offset from GMT including
*** daylight savings. Result is returned in minutes.
************************************************************************
PUBLIC __TimeZone

*** Cache the timezone so this is fast
IF VARTYPE(__TimeZone) = "N"
RETURN __TimeZone
ENDIF

DECLARE integer GetTimeZoneInformation IN Win32API ;
STRING @ TimeZoneStruct

lcTZ = SPACE(256)

lnDayLightSavings = GetTimeZoneInformation(@lcTZ)
lnOffset = CharToBin(SUBSTR(lcTZ,1,4),.T.)

*** Subtract an hour if daylight savings is active
IF lnDaylightSavings = 2
lnOffset = lnOffset - 60
ENDIF

__TimeZone = lnOffset

RETURN lnOffSet

************************************************************************
FUNCTION CharToBin(lcBinString,llSigned)
****************************************
*** Function: Binary Numeric conversion routine.
*** Converts DWORD or Unsigned Integer string
*** to Fox numeric integer value.
*** Pass: lcBinString - String that contains the binary data
*** llSigned - if .T. uses signed conversion
*** otherwise value is unsigned (DWORD)
*** Return: Fox number
************************************************************************
LOCAL m.i, lnWord

lnWord = 0
FOR m.i = 1 TO LEN(lcBinString)
lnWord = lnWord + (ASC(SUBSTR(lcBinString, m.i, 1)) * (2 ^ (8 * (m.i - 1))))
ENDFOR

IF llSigned AND lnWord > 0x80000000
lnWord = lnWord - 1 - 0xFFFFFFFF
ENDIF

RETURN lnWord
 
Avsalf,

Rick's function is great to get the current UTC and allows a VFP application to record a current event's time consistently.

Although being a good starting point, handling UTC records in an application requires more than that: a UTC-aware application should know how to record time data in the future, how to interpret time in the past, and how to handle the present time for different places of the planet.

If you're interested in making your applications UTC-aware, you might consider having a look at the UTCDatetime repository at It provides a full-blown UTC extension to VFP applications that addresses UTC and local time records in the past, the present, and the foreseeable future.

Although you have access to the source code, there is a compiled application readily available for convenience:
Code:
DO LOCFILE("UTC.APP")

After that, a [tt]_Screen.UTC[/tt] object offers a set of methods and properties to process UTC and its relation to local time.

The repository includes a few code examples for you to try (like "Calculate the duration of international flights" or "Calculate the local time of historical events in different places"). Here's how to "Get the current UTC and local times for two cities in the USA":

Code:
LOCAL m.UTCTime AS Datetime

m.UTCTime = _Screen.UTC.Now()

? "UTC:", m.UTCTime
? "In New York:", _Screen.UTC.LocalTime(m.UTCTime, "America/New_York")
? "In Los Angeles:", _Screen.UTC.LocalTime(m.UTCTime, "America/Los_Angeles")

As I write, this displays:

Captura_de_ecr%C3%A3_2021-03-14_013346_c6rrqf.png
 
Thanks for posting this, Avsalf.

I tend to disagree with your statement that UTC-related "problems don’t usually show up until much later in the lifetime of the application." Applications that span time zones have been around for decades, and there is no reason not to plan for the relevant issues from the outset, as many of us do.

Still, it's good that you have drawn attention to the issues for any programmers who are no aware of them.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
It's nice to see discussions on "variations of a theme".

This thread reminded me of a thread I started Link which works very well for my application. I will follow the alternatives described above with interest.

Regards,

David.

Recreational Developer / End User of VFP.
 
In our time of more online meetings, which in part are international, you surely want to be able to inform everyone in his or her local time, to give just another example of why this is important.

As easy as it's to know the local time by DATETIME(), as easy is it to know UTC time by the GetSystmTime API function, then use knowledge about DST or not and to know the bias of local to UTC time. And when determining differences also take into account an earlier or later datetime might be with a switch between DST or not, either by different countries supporting or not supporting DST shifts. One hour is skipped when the time springs forward and another hour exists double when time falls back. That's a thing I think every night guard working on these days will appreciate.

I think the SQL Server datetime including timezone info is handling this the same way, mainly storing the UTC time to be able to calculate local time as of then in the time zone stored. To get the local time from UTC you not necessarily need to add the current DST bias, but the DST bias as it was at that UTC time.

The timezone information is of secondary importance, once you have UTC (without DST) you can compute what local time this was in which timezone if you have all info about the normal time zone offset and the DST offset at that UTC time. This means, you need to have data about the dates of DST switching for each time zone, maybe even differing for different countries although they are in the same time zone.

In short, all you need is UTC time and a database of time zone information and DST switching for the world. Then you can return what local time it was for any timezone/country combination.
And regarding that database of all switches for the whole world, MS offers a dynamic version of the GetTimezoneInformation:
If you really want to be to the point about time handling you need to use this.




Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top