Functions to get the elapsed millisecond and second times since the start of 2020

Share your advanced PureBasic knowledge/code with the community.
Axeman
User
User
Posts: 89
Joined: Mon Nov 03, 2003 5:34 am

Functions to get the elapsed millisecond and second times since the start of 2020

Post by Axeman »

These two functions get the approximate elapsed millisecond and second times since the start of 2020.
The purpose of these functions is to obtain a non-repeating value (to seed a random number generator, etc). They are not meant to be precise.

Code: Select all



Procedure.q GetMillisecTime()
; Returns the approximate number of milliseconds elapsed since the start of 2020. The return value is a quad (64 bit integer).
; This function is designed to obtain a non-repeating value (to seed a random number generator, etc). It is not meant to be precise.
; -
; https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtime
; https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime

Protected time_info.SYSTEMTIME, elapsed.q

GetSystemTime_( @time_info )
elapsed = ( time_info\wYear - 2020 ) * ( 365 * 24 * 60 * 60 * 1000 )
elapsed + ( time_info\wMonth - 1 ) * ( 31 * 24 * 60 * 60 * 1000 ) ; We will use the maximum number of days in a month here so that we don't need to care about leap years and day-counts for individual months.
elapsed + ( time_info\wDay * ( 24 * 60 * 60 * 1000 ) )
elapsed + ( time_info\wHour * ( 60 * 60 * 1000 ) )
elapsed + ( time_info\wMinute * ( 60 * 1000 ) )
elapsed + ( time_info\wSecond * 1000 )
elapsed + time_info\wMilliseconds

ProcedureReturn elapsed
EndProcedure



Procedure.l GetSecondTime()
; Returns the approximate number of seconds elapsed since the start of 2020. The return value is a long (32 bit integer).
; This function is designed to obtain a non-repeating value (to seed a random number generator, etc). It is not meant to be precise.
; -
; https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtime
; https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime

Protected time_info.SYSTEMTIME, elapsed.l

GetSystemTime_( @time_info )
elapsed = ( time_info\wYear - 2020 ) * ( 365 * 24 * 60 * 60 )
elapsed + ( time_info\wMonth - 1 ) * ( 31 * 24 * 60 * 60 ) ; We will use the maximum number of days in a month here so that we don't need to care about leap years and day-counts for individual months.
elapsed + ( time_info\wDay * ( 24 * 60 * 60 ) )
elapsed + ( time_info\wHour * ( 60 * 60 ) )
elapsed + ( time_info\wMinute * 60 )
elapsed + time_info\wSecond

ProcedureReturn elapsed
EndProcedure


Debug GetMillisecTime()
Debug GetSecondTime()


User avatar
NicTheQuick
Addict
Addict
Posts: 1224
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Functions to get the elapsed millisecond and second times since the start of 2020

Post by NicTheQuick »

I don't get why you return a 32 bit value instead of 64 bit. I also don't get why you need this for a random seed. You simply can use CryptRandom() for that purpose. It returns a real random number. :)
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Functions to get the elapsed millisecond and second times since the start of 2020

Post by infratec »

For GetSecondTime() ...

this is accurate:

Code: Select all

Debug Date() - Date(2020, 1, 1, 0, 0, 0)
Or a bit optimized:

Code: Select all

#Date20200101000000 = 1577836800
Debug Date() - #Date20200101000000
User avatar
Demivec
Addict
Addict
Posts: 4086
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Functions to get the elapsed millisecond and second times since the start of 2020

Post by Demivec »

infratec wrote: Wed Jan 12, 2022 1:53 pm For GetSecondTime() ...

this is accurate:

Code: Select all

Debug Date() - Date(2020, 1, 1, 0, 0, 0)
Or a bit optimized:

Code: Select all

#Date20200101000000 = 1577836800
Debug Date() - #Date20200101000000

That is only guaranteed to be functional for 16 more years. That begins to affect the longevity of code more and more.
Axeman
User
User
Posts: 89
Joined: Mon Nov 03, 2003 5:34 am

Re: Functions to get the elapsed millisecond and second times since the start of 2020

Post by Axeman »

NicTheQuick wrote: Wed Jan 12, 2022 1:30 pm I don't get why you return a 32-bit value instead of 64 bit. I also don't get why you need this for a random seed. You simply can use CryptRandom() for that purpose. It returns a real random number. :)
There are two functions. One is designed to return millisecond values via a quad integer and is intended for 64-bit executables. These values should work for several millennia. The other function returns seconds as a long integer and is intended for 32-bit executables. This value should work up till around the year 2088. If you prefer them to return different value types then change them to do that.

Both CryptRandom() and the standard Random() command return algorithmically generated random numbers. CryptRandom() isn't magic, it just uses a more processing-intensive algorithm that probably sources seed input more widely from the user's system than Random() does. In a causal universe, there is no such thing as a real random number. CryptRandom() is also overkill for a lot of situations where a faster and less random function is acceptable. Using these for random number seeds was just an example. I'm also using them to generate non-repeating sequential (but not contiguous) numbers for filenames, for example.
User avatar
NicTheQuick
Addict
Addict
Posts: 1224
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Functions to get the elapsed millisecond and second times since the start of 2020

Post by NicTheQuick »

I've got no Windows anywhere at home but you should be able to convert the value from GetSystemTime_() using SystemTimeToFileTime_() to LPFILETIME and then you can convert that value to a 64 bit integer. File times have a resolution of 100 ns, so it should work exactly like your solution but better because it does not assume that every month has 31 days.

By the way. On Linux you can do it like this:

Code: Select all

; From <bits/time.h>
; struct timeval
;   {
;     __time_t tv_sec;		/* Seconds.  */
;     __suseconds_t tv_usec;	/* Microseconds.  */
;   };

Structure timeval
	tv_sec.q
	tv_usec.q
EndStructure

Define tv.timeval
Define milliseconds.q

gettimeofday_(@tv, #Null)
milliseconds = tv\tv_sec * 1000 + tv\tv_usec / 1000
Debug milliseconds
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: Functions to get the elapsed millisecond and second times since the start of 2020

Post by BarryG »

Axeman wrote: Wed Jan 12, 2022 12:09 amThese two functions get the approximate elapsed millisecond and second times since the start of 2020.
The purpose of these functions is to obtain a non-repeating value (to seed a random number generator, etc). They are not meant to be precise.
This does what you said above and doesn't repeat, but the string operations might be too slow if speed is a critical issue with what you're doing? It's short and sweet, though. Obviously you'll convert the string with Val() when using it to seed your random number generator.

Code: Select all

GetLocalTime_(time.SYSTEMTIME)
Debug Str(Date(2020,1,1,0,0,0)+Date())+LSet(Str((time\wMilliseconds)),3,"0")
Post Reply