I’m having a senior moment ![]()
I have a Win32 SystemTime structure with all the individual components of a time stamp (IE, “2010-01-26 @ 07:53:41.0898”) , what’s the easiest way to convert it into the # of seconds since the linux date epoch (1970-01-01 00:00:00) ?
Hi Paul
StringTheory has some methods for those things but assuming you don’t have that, just extract the date out of your time stamp convert to Clarion date then subtract date(1,1,1970) and multiply that by the number of seconds in a day
(ie. 24 * 60 * 60).
Then get the time and convert hours and minutes to seconds and add that on.
Usually people use equates for the various conversions as Mark does here:
A search for your question turned up to convert it to a FILETIME (number of 100-nanosecond intervals since January 1, 1601 UTC) then some simple math to offset to 1970 and divide for seconds. You will need to use Clarion’s 64 bit RTL include i64.inc
Int64 GetSystemTimeAsUnixTime()
{
//Get the number of seconds since January 1, 1970 12:00am UTC
//Code released into public domain; no attribution required.
const Int64 UNIX_TIME_START = 0x019DB1DED53E8000; //January 1, 1970 (start of Unix epoch) in "ticks"
const Int64 TICKS_PER_SECOND = 10000000; //a tick is 100ns
FILETIME ft;
GetSystemTimeAsFileTime(&ft); //returns ticks in UTC
//Copy the low and high parts of FILETIME into a LARGE_INTEGER
//This is so we can access the full 64-bits as an Int64 without causing an alignment fault
LARGE_INTEGER li;
li.LowPart = ft.dwLowDateTime;
li.HighPart = ft.dwHighDateTime;
//Convert ticks since 1/1/1970 into seconds
return (li.QuadPart - UNIX_TIME_START) / TICKS_PER_SECOND;
}
Seems like using Clarion functions would be easier, maybe
Epoch=(Date(st.wMonth, st.wDay, st.wYear) |
- Date(1,1,1970) ) *24*60*60 |
+ st.wHour * 60 * 60 |
+ st.wMinute * 60 |
+ st.wSecond
Converting FileTime to SystemTime and vice versa is the easy part, the hard part is that this is C6 and I don’t have a i64.inc ![]()
But thanks to all your suggestions I will play more tomorrow.
You should be able to do it using a DECIMAL(21) or (19)
const Int64 UNIX_TIME_START = 0x019DB1DED53E8000; //January 1, 1970 (start of Unix epoch) in "ticks"
Using the Windows Calculator Hex of above = 116444736000000000 Decimal
Divide by 10,000,000 = 11644473600 so its a smaller number
Seconds1601_1970 DECIMAL(11,0,11644473600)
FT_Dec DECIMAL(21)
FT_Dec = ft.dwHighDateTime
FT_Dec *= 2 ^ 32 ! 2^32=4,294,967,296
FT_Dec += ft.dwLowDateTime
FT_Dec /= 10000000 ! / 10,000,000 from nano to seconds
FT_Dec -= Seconds1601_1970
map
module('windows')
OS_GetSystemTime(*NET_SYSTEMTIME lpSystemTime), pascal, raw, name('GetSystemTime'), dll(1)
end
end
NET_SYSTEMTIME group, type
wYear ushort
wMonth ushort
wDayOfWeek ushort
wDay ushort
wHour ushort
wMinute ushort
wSecond ushort
wMilliseconds ushort
end
!------------------------------------------------------------------------------
! Returns a REAL containing the milliseconds elapsed since 1 January 1970 00:00:00 UTC up until now
_NetAll.GetElapsedTimeUTC PROCEDURE (Long pBaseDate=61730) ! 61730 = 1 jan 1970
msPerDay real(24 * 60 * 60 * 1000) ! don't make this an equate, needs to force the calc below to be real.
msPerHour equate (60 * 60 * 1000)
msPerMinute equate (60 * 1000)
msPerSecond equate (1000)
today long
ans Real
tim Group(NET_SYSTEMTIME).
code
OS_GetSystemTime(tim) ! returned time is for UTC not local time
today = date(tim.wMonth,tim.wDay,tim.wYear)
ans = (( today - pBaseDate ) * msPerDay ) + (tim.wHour * msPerHour) + (tim.wMinute * msPerMinute) + (tim.wSecond * msPerSecond) + tim.wMilliseconds
return ans
!------------------------------------------------------------------------------
! Extracts Clarion Date from a Unix date/time (which is stored as Seconds since Jan 1 1970)
_NetAll.UnixToClarionDate Procedure(Long p_DateTime)
code
if p_DateTime >= 86400
return (int(p_DateTime / 86400) + 61730) ! 61730 = Date(1,1,1970)
else ! 86400 = seconds in 1 day
return 0
end
!------------------------------------------------------------------------------
! Extracts Clarion Time from a Unix date/time (which is stored as Seconds since Jan 1 1970)
_NetAll.UnixToClarionTime Procedure(Long p_DateTime)
code
if p_DateTime < 0
return 0
end
return(1+(p_DateTime % 86400) * 100) ! 86400 = seconds in 1 day
!------------------------------------------------------------------------------
! Converts a Clarion Date & Time to a Unix date/time (which is stored as Seconds since Jan 1 1970)
_NetAll.ClarionToUnixDate Procedure(Long p_Date, Long p_Time)
code
if p_Date > 61730 ! 61730 = date(1,1,1970)
return(((p_Date-61730)*86400) + (p_Time / 100)) ! 86400 = seconds in 1 day
else
return((p_Time / 100))
end
!------------------------------------------------------------------------------