1. Date/Time conversions

I have a database of transactions that have a date/time stamp formatted as a text string "YYYYMMDDHHMMSS" that is in GMT time. I need to convert these to local time. I've been looking at the Win32 function BOOL WINAPI SystemTimeToTzSpecificLocalTime( in_opt LPTIME_ZONE_INFORMATION lpTimeZone, in LPSYSTEMTIME lpUniversalTime, out LPSYSTEMTIME lpLocalTime)

as a way to do this work. However the structures lpUniversalTime & lpLocalTime use 16bit (word) values. I'm not sure how to populate the allocated memory structures in order to use them. Any help is appreciated. Of course if there is a better/easier way to do this I'm all ears. Thanks

    » topic index » view message » categorize

2. Re: Date/Time conversions

Hi cp,

There are probably easier ways (and there are a few time routines in the archive). But I went ahead and wrapped your desired function. Here's the example code:

include std/dll.e 
include std/win32/msgbox.e 
include std/machine.e 
 
constant 
  gtKernel32 = open_dll("kernel32.dll"), 
  systemTimeToTzSpecificLocalTime = define_c_func(gtKernel32, "SystemTimeToTzSpecificLocalTime", {C_POINTER,C_POINTER,C_POINTER}, C_BOOL) 
 
atom sizeOf_SystemTime =  
   2 --WORD wYear; 
  +2 --WORD wMonth; 
  +2 --WORD wDayOfWeek; 
  +2 --WORD wDay; 
  +2 --WORD wHour; 
  +2 --WORD wMinute; 
  +2 --WORD wSecond; 
  +2 --WORD wMilliseconds; 
 
-- These are pointers to SYSTEMTIME structures 
atom systemTimeInPtr = allocate(sizeOf_SystemTime) -- UTC time to be converted 
atom systemTimeOutPtr = allocate(sizeOf_SystemTime) -- GMT time resulting 
 
-- Populate SYSTEMTIME structure 
procedure populateSystemTime(atom systemTimePtr, sequence date) 
  -- systemTimePtr: pointer to allocated memory 
  -- date: {YYYY,MM,DD,HH,MM,SS} 
  poke2(systemTimePtr   ,date[1]) -- Year 
  poke2(systemTimePtr+2 ,date[2]) -- Month 
  poke2(systemTimePtr+4 ,0      ) -- Day of week 
  poke2(systemTimePtr+6 ,date[3]) -- Day 
  poke2(systemTimePtr+8 ,date[4]) -- Hour 
  poke2(systemTimePtr+10,date[5]) -- Minute 
  poke2(systemTimePtr+12,date[6]) -- Second 
  poke2(systemTimePtr+14,0      ) -- Milisecond 
end procedure 
 
-- Parse the time from a SYSTEMTIME structure 
function getSystemTime(atom systemTimePtr) 
  return { 
     peek2s(systemTimePtr   ) -- Year 
    ,peek2s(systemTimePtr+2 ) -- Month 
    ,peek2s(systemTimePtr+6 ) -- Day 
    ,peek2s(systemTimePtr+8 ) -- Hour 
    ,peek2s(systemTimePtr+10 ) -- Minute 
    ,peek2s(systemTimePtr+12 ) -- Second 
  } 
end function 
 
sequence gmt0time = {2012,03,25,23,30,00} 
?gmt0time 
 
-- Put inside SYSTEMTIME, our current time 
populateSystemTime(systemTimeInPtr, gmt0time) -- This is UTC (GMT 0) time 
 
-- Do the conversion, NULL as the first parameter uses current active time zone (in my case, GMT-3) 
if c_func(systemTimeToTzSpecificLocalTime,{NULL,systemTimeInPtr,systemTimeOutPtr}) = 0 then 
    puts(1,"Error calling SystemTimeToTzSpecificLocalTime") 
    abort(1) 
end if 
 
-- Print the converted system time 
?getSystemTime(systemTimeOutPtr) 
-- In my machine (GMT-3) this prints {2012,3,25,20,30,0} -- Which is correct, 3 hours less than UTC 
 
-- Free used pointers 
free(systemTimeInPtr) 
free(systemTimeOutPtr) 

WORDs are 16-bit (2 bytes) in memory.

Cheers, Guillermo

    » goto parent     » topic index » view message » categorize

3. Re: Date/Time conversions

Guillermo

Thanks very much. I was trying to do this in v3.1 - Looks like a good reason to upgrade to 4.x to gain access to the poke2 function!

    » goto parent     » topic index » view message » categorize

4. Re: Date/Time conversions

cp said...

Any help is appreciated. Of course if there is a better/easier way to do this I'm all ears.

With Eu4, the std/datetime.e module has many date-time routines that can be used in either Windows or Linux environments. However, I'm surprised to find that is doesn't include converting between GMT and local times. I'll add that as an enhancement request. however, it does have Add and Subtract functions so if you know the time zone difference you can calculate the local time from GMT.

    » goto parent     » topic index » view message » categorize

5. Re: Date/Time conversions

Cool, I actually tried not to use specific 4.0 features but I didn't remember poke2/peek2 weren't there.

PS: My code could be modified to use sequences when peeking/poking if you're looking for speed crazy speed :)

Edit: If I understood correctly, you can see the difference between GMT 0 and your current timezone using now() and now_gmt() on Eu4 http://openeuphoria.org/docs/std_datetime.html#_1030_now_gmt

Edit2: It worked! :)
FYI, this may not be so accurate since we are calling now and now_gmt which in the middle the system could hog or something (weird but could happen), if you really need to be sure, you can remove the seconds from now and now_gmt and set them to 0 (if your system is so busy for a minute, there's a bigger problem!).

 
include std/datetime.e as dtf 
 
sequence rightnow = dtf:now() 
sequence rightnowgmt0 = dtf:now_gmt() 
-- Calculate the difference between your machine timezone and GMT0 
atom gmt0diff = dtf:diff(rightnowgmt0, rightnow) 
 
-- Create Euphoria datetime 
sequence yourdate = dtf:new(2012,3,25,23,30,0) 
 
-- Calculate difference 
?dtf:add(yourdate,gmt0diff,dtf:SECONDS) 
-- Print {2012,3,25,20,30,0} which is GMT-3! :) 
    » goto parent     » topic index » view message » categorize

6. Re: Date/Time conversions

gbonvehi said...

Hi cp,

There are probably easier ways (and there are a few time routines in the archive). But I went ahead and wrapped your desired function. Here's the example code:

For fun, I've rewritten your code using the new (still experimental) memstruct facilities:

include std/memstruct/windows.e 
 
memstruct SYSTEMTIME 
	WORD wYear 
	WORD wMonth 
	WORD wDayOfWeek 
	WORD wDay 
	WORD wHour 
	WORD wMinute 
	WORD wSecond 
	WORD wMilliseconds 
end memstruct 
 
procedure populateSystemTime(atom systemTimePtr, sequence date) 
-- systemTimePtr: pointer to allocated memory 
-- date: {YYYY,MM,DD,HH,MM,SS} 
	systemTimePtr.SYSTEMTIME.wYear         = date[1] 
	systemTimePtr.SYSTEMTIME.wMonth        = date[2] 
	systemTimePtr.SYSTEMTIME.wDayOfWeek    = 0 
	systemTimePtr.SYSTEMTIME.wDay          = 6 
	systemTimePtr.SYSTEMTIME.wHour         = 8 
	systemTimePtr.SYSTEMTIME.wMinute       = date[5] 
	systemTimePtr.SYSTEMTIME.wSecond       = date[6] 
	systemTimePtr.SYSTEMTIME.wMilliseconds = 0 
end procedure 
 
-- Parse the time from a SYSTEMTIME structure 
function getSystemTime(atom systemTimePtr) 
return { 
	systemTimePtr.SYSTEMTIME.wYear, 
	systemTimePtr.SYSTEMTIME.wMonth, 
	systemTimePtr.SYSTEMTIME.wDay, 
	systemTimePtr.SYSTEMTIME.wHour, 
	systemTimePtr.SYSTEMTIME.wMinute, 
	systemTimePtr.SYSTEMTIME.wSecond 
	} 
end function  
 
-- These are pointers to SYSTEMTIME structures 
atom systemTimeInPtr = allocate( sizeof( SYSTEMTIME ) ) -- UTC time to be converted 
atom systemTimeOutPtr = allocate( sizeof( SYSTEMTIME ) ) -- GMT time resulting 

Matt

    » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu