Ian Branch 127 Posted August 1, 2021 Hi Guys, Is there a way to retrieve the actual UTC date/time? All the routines I can find work backwards from local date/time. Regards & TIA, Ian Share this post Link to post
Wagner Landgraf 43 Posted August 1, 2021 UTCNow := TTimeZone.Local.ToUniversalTime(Now); Share this post Link to post
Ian Branch 127 Posted August 1, 2021 Hi Wagner, Thank you for your suggestion. My read of "TTimeZone.Local.ToUniversalTime" in the Delphi docs is that it derives the UTC from your Local. This is no good if the time on your local PC is incorrect. This isn't what I am after, I am after the actual UTC date/time. Regards, Ian Share this post Link to post
David Heffernan 2345 Posted August 1, 2021 2 minutes ago, Ian Branch said: Hi Wagner, Thank you for your suggestion. My read of "TTimeZone.Local.ToUniversalTime" in the Delphi docs is that it derives the UTC from your Local. This is no good if the time on your local PC is incorrect. This isn't what I am after, I am after the actual UTC date/time. Regards, Ian What source do you want to use for the time, given that you've ruled out the local computer? Share this post Link to post
Ian Branch 127 Posted August 1, 2021 Hi David, Well I guess that is where I am a little lost. Hmmm. I'm guessing GMT date time doesn't have daylight savings and is therefore effectively UTC time, so I guess the trick would be to source from a GMT clock somehow?? Ian Share this post Link to post
Dave Nottage 552 Posted August 1, 2021 1 hour ago, Ian Branch said: I guess the trick would be to source from a GMT clock somehow?? You might want to read this: 1 Share this post Link to post
Angus Robertson 573 Posted August 2, 2021 function IcsGetUTCTime: TDateTime; var SystemTime: TSystemTime; begin GetSystemTime(SystemTime); with SystemTime do begin Result := EncodeTime (wHour, wMinute, wSecond, wMilliSeconds) + EncodeDate (wYear, wMonth, wDay); end ; end; Angus Share this post Link to post
dummzeuch 1495 Posted August 2, 2021 If you don't want to use the local time of the computer, you need a different time source. There is of course NTP (network time protocol), if you have an internet connection. Then there are various hardware solutions, but if those are available they are usually already used to set the local time (actually, recent Windows already uses NTP to adjust the system time). And then there is GPS, which also contains UTC in various of its NMEA sentences. Always keep in mind that there is a delay between the source sending the time and your program receiving it. Share this post Link to post
David Heffernan 2345 Posted August 2, 2021 You are concentrating on the time zone, but that's not your issue at all. When you get time from somewhere, you will be able to convert to UTC because you will know the time zone associated with the time. Your problem seems to be that you want to use an authorative time source. You should do research on that rather than worrying about time zone conversion. 1 Share this post Link to post
Ian Branch 127 Posted August 2, 2021 Angus, Thank you, correct me if I am wrong but this appears to use the local time as its basis. dummzeuch, Thank you. I am aware of various hardware methods but the End User isn't interested. He has the habit of letting his Server clock 'run free' and after a couple of months it can be 2+ minutes out. He doesn't want to sync with nntp as his Country plays funny with daylight savings. Additionally he is forgetful (did I say lazy) about checking and correcting the server. So, I thought if could detect the time difference between UTC and his Server clock I could overtly flag (remind) him that it needs adjusting. David, Absolutely, that is why I thought of reading a UTC/GMT clock from somewhere. Is it possible to read the date/time form one of those internet time sources? Regards and thanks to all, Ian Share this post Link to post
dummzeuch 1495 Posted August 2, 2021 18 minutes ago, Ian Branch said: Is it possible to read the date/time form one of those internet time sources? That's the whole point of NTP. Share this post Link to post
Ian Branch 127 Posted August 2, 2021 All, Nothing like a kick in the right direction. Forest & Trees and all that. Oh so simple using Indy's idDayTime component. IdDayTime1.Host := 'time-a.nist.gov'; Label1.Caption := IdDayTime1.DayTimeStr; My thanks to all for your patience and suggestions. Regards, Ian Share this post Link to post
Angus Robertson 573 Posted August 2, 2021 Quote Thank you, correct me if I am wrong but this appears to use the local time as its basis. GetSystemTime function (sysinfoapi.h) Retrieves the current system date and time in Coordinated Universal Time (UTC) format. To retrieve the current system date and time in local time, use the GetLocalTime function. https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtime Angus Share this post Link to post
Fr0sT.Brutal 899 Posted August 2, 2021 3 hours ago, Ian Branch said: He doesn't want to sync with nntp as his Country plays funny with daylight savings. NTP retrieves base time and has nothing to do with timezones. As general advice, it's wise to get rid of local timestamps everywhere but user display and use GMT (that is, 0 timezone; it's also frequently referred to as UTC but they're a bit different; nevertheless, in most cases they could be considered identical) Share this post Link to post
timfrost 75 Posted August 2, 2021 However "funny" your user's country plays with daylight savings, the settings should be promptly reflected in the IANA database, which you can incorporate using the functions at https://github.com/pavkam/tzdb. If you are prepared to monitor updates (every few months) and recompile your application with the latest include file (many changes are historical only), then it is simple to convert UTC to a local timezone, including DST when applicable, which can be displayed accurately for users wherever they are in the world. Share this post Link to post
Fr0sT.Brutal 899 Posted August 2, 2021 47 minutes ago, timfrost said: If you are prepared to monitor updates (every few months) and recompile your application with the latest include file (many changes are historical only), then it is simple to convert UTC to a local timezone, including DST when applicable, which can be displayed accurately for users wherever they are in the world This proves once again my position: don't mess with local time wherever possible 🙂 Share this post Link to post
Remy Lebeau 1376 Posted August 2, 2021 (edited) 8 hours ago, Angus Robertson said: GetSystemTime function (sysinfoapi.h) Retrieves the current system date and time in Coordinated Universal Time (UTC) format. GetSystemTime() is dependent on the local computer's clock/timezone being configured properly, which Ian doesn't want to rely on. Edited August 2, 2021 by Remy Lebeau Share this post Link to post
Ian Branch 127 Posted August 2, 2021 HI Guys, Not to prolong this thread any longer than necessary... This is what I have att. 1. GetSystemTime returns a 'UTC' time but it seems it is derived from the local PC time. - No good to me. 2. IdSNTP1.Host := 'time-a.nist.gov'; returns my local time. - No good to me. 3. IdDayTime1.Host := 'time-a.nist.gov'; returns what appears to be a complete UTC date/time string. - If this is true then it is exactly what I need. I continue to experiment. Regards and again thanks to all for your inputs. Ian Share this post Link to post
Remy Lebeau 1376 Posted August 2, 2021 (edited) 3 hours ago, Ian Branch said: 1. GetSystemTime returns a 'UTC' time but it seems it is derived from the local PC time. - No good to me. Yes, it is the UTC time of the local PC clock. Quote 2. IdSNTP1.Host := 'time-a.nist.gov'; returns my local time. - No good to me. Internally, it converts the result to local time, yes. But the NTP protocol itself (RFC 5905) reports time in UTC. Quote 3. IdDayTime1.Host := 'time-a.nist.gov'; returns what appears to be a complete UTC date/time string. - If this is true then it is exactly what I need. Technically, the DAYTIME protocol (RFC 867) does not define any particular string format or locale for the output, so it could be anything the server wants, in any format, any timezone, etc. The TIME protocol (RFC 868) is expressed in UTC. Indy's TIdTime and TIdTimeUDP implement this protocol. They both convert the result to local time when queried as a TDateTime, same as TIdSNTP does, however you can also get the original UTC response in UInt32 format instead via the DateTimeCard property. Per https://tf.nist.gov/tf-cgi/servers.cgi, NIST suggests that all clients of NIST servers update to using the NTP protocol, which is what TIdSNTP implements, which you have already ruled out as a solution. TIdSNTP does not expose access to the UTC response. Edited August 2, 2021 by Remy Lebeau 1 Share this post Link to post
Ian Branch 127 Posted August 3, 2021 Hi Remy, Thank you for the vey informative response. Appreciated. I have ended up using IdSNTP1.Host := 'time-a.nist.gov'; as it gives me a direct comparison between what the time should be v what the PC says. This I can work with. Regards & Thanks again, Ian Share this post Link to post
Fr0sT.Brutal 899 Posted August 3, 2021 13 hours ago, Remy Lebeau said: GetSystemTime() is dependent on the local computer's clock/timezone being configured properly What makes you think timezone plays a role here? Share this post Link to post
Angus Robertson 573 Posted August 3, 2021 Any API that requests system time is dependent on the computer clock being set correctly and with the correct time zone. Windows will then use NTP to keep it correct. Relying on NTP time is dangerous since the internet is not reliable, nor are NTP servers, nor DNS to reach them. Relying on a single NTL server is also dangerous, unless it's hosted across distributed hosts, like time.google.com or time.cloudflare.com, nist.gov has at least 15 different host names, don't know if they are distributed. Angus Share this post Link to post
darnocian 77 Posted August 3, 2021 In my opinion, I'd try fix the OS configuration, or use a 3rd party if the default provided by the OS isn't good enough. From an application perspective, there should be a level of trust on basic services provided by system, otherwise there would be a lot of app bloat if everyone had to distrust them... When it comes to the APIs we use from the OS or the RTL, the key thing we need to pay attention to is the locale configuration (defined by the OS again), and use the appropriate toUTC/fromUTC type functionality. This is especially important when applying these functions appropriately when obtaining data from 3rd party sources and converting the timestamps appropriately, which would normally be sourced in UTC. On windows (desktop and server), there is w32tm.exe (windows time service) https://docs.microsoft.com/en-us/windows-server/networking/windows-time-service/windows-time-service-tools-and-settings. On my workstation this was disabled till I enabled it, but the other benefit is that within a larger organisation, the sysadmins could script something to deploy and enable appropriately with whatever the standard is so that everyone was covered consistently. I have worked on time sensitive apps before where we had 3rd party time agents on the host machine that synchronised the time, and custom libraries that worked with those agents, but this was because there was a very very low tolerance for any time drift at any time because the application was financial in nature working on financial market data in realtime and logging required more granular timestamp information. I'd try to stick to RTL functions or standard system calls like what @Wagner Landgraf referenced above, but that is my opinion. Share this post Link to post
dummzeuch 1495 Posted August 3, 2021 6 hours ago, Angus Robertson said: Relying on NTP time is dangerous since the internet is not reliable, nor are NTP servers, nor DNS to reach them. Relying on a single NTL server is also dangerous, unless it's hosted across distributed hosts, like time.google.com or time.cloudflare.com, nist.gov has at least 15 different host names, don't know if they are distributed. That depends on the definition of "dangerous". As long as a failure to contact an NTP server does not crash the system and does not create any wrong data, it might be an annoyance but it's not dangerous in my opinion. But yes, using an NTP service with distributed hosts is more likely to work. Of course that leaves the internet connection and the DNS as possible causes for failure as you already stated. Share this post Link to post