Realm

Seconds since Epoch (a.k.a. Unix Timestamp)

4 posts in this topic

#1 ·  Posted (edited)

After Several Minutes searching the forums for a simple solution to calculating for the Unix Time, as required for another project I am working on, I was astonished to not find one clean and universal solution. After looking over the helpfile, I noticed one simple solution given in the example with _DateDiff(). However it did not account for my current timezone or daylight savings time.

Without further ado... This is my example of Calculating for a current Unix Time stamp or  seconds since Jan, 1st, 1970 00:00:00 GMT.

This function will account for your timezone as well as for daylight savings time.

Update: v0.3

-Added Function to revert a Unix Time stamp into Date form.

-Added parameter to original _GetUnixTime() allowing for a custom date since Jan 1st 1970 to be passed and converted to Unix Time.

#include <Date.au3>
#include <Array.au3>
#include <Constants.au3>

Local $iUnixTime1 = _GetUnixTime()
MsgBox($MB_SYSTEMMODAL, "Unix Timestamp", "Seconds Since Jan, 1st, 1970 00:00:00 GMT" & @CRLF & $iUnixTime1)

Local $sUnixDate1 = _GetDate_fromUnixTime($iUnixTime1)
MsgBox($MB_SYSTEMMODAL, "Unix Timestamp", "Get Date from Unix Timestamp in Local Time" & @CRLF & $sUnixDate1)

$sUnixDate1 = _GetDate_fromUnixTime($iUnixTime1, False)
MsgBox($MB_SYSTEMMODAL, "Unix Timestamp", "Get Date from Unix Timestamp with $iReturnLocal = False which returns UTC Time" & @CRLF & $sUnixDate1)

Local $iUnixTime2 = _GetUnixTime('2013/01/01 00:00:00')
MsgBox($MB_SYSTEMMODAL, "Unix Timestamp", "Seconds since 2013/01/01 00:00:00" & @CRLF & $iUnixTime2)

; Get timestamp for input datetime (or current datetime).
Func _GetUnixTime($sDate = 0);Date Format: 2013/01/01 00:00:00 ~ Year/Mo/Da Hr:Mi:Se

    Local $aSysTimeInfo = _Date_Time_GetTimeZoneInformation()
    Local $utcTime = ""

    If Not $sDate Then $sDate = _NowCalc()

    If Int(StringLeft($sDate, 4)) < 1970 Then Return ""

    If $aSysTimeInfo[0] = 2 Then ; if daylight saving time is active
        $utcTime = _DateAdd('n', $aSysTimeInfo[1] + $aSysTimeInfo[7], $sDate) ; account for time zone and daylight saving time
    Else
        $utcTime = _DateAdd('n', $aSysTimeInfo[1], $sDate) ; account for time zone
    EndIf

    Return _DateDiff('s', "1970/01/01 00:00:00", $utcTime)
EndFunc   ;==>_GetUnixTime

;$blTrim: Year in short format and no seconds.
Func _GetDate_fromUnixTime($iUnixTime, $iReturnLocal = True)
    Local $aRet = 0, $aDate = 0
    Local $aMonthNumberAbbrev[13] = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
    Local $timeAdj = 0
    If Not $iReturnLocal Then
        Local $aSysTimeInfo = _Date_Time_GetTimeZoneInformation()
        Local $timeAdj = $aSysTimeInfo[1] * 60
        If $aSysTimeInfo[0] = 2 Then $timeAdj += $aSysTimeInfo[7] * 60
    EndIf

    $aRet = DllCall("msvcrt.dll", "str:cdecl", "ctime", "int*", $iUnixTime + $timeAdj )

    If @error Or Not $aRet[0] Then Return ""

    $aDate = StringSplit(StringTrimRight($aRet[0], 1), " ", 2)

    Return $aDate[4] & "/" & StringFormat("%.2d", _ArraySearch($aMonthNumberAbbrev, $aDate[1])) & "/" & $aDate[2] & " " & $aDate[3]
EndFunc   ;==>_GetUnixDate

Enjoy!

Realm

Update: >Added some functionality and a suggestion from FireFox

Edited by Realm
Included thegebi's revision and added commenting to MessageBoxes to better explain the functions. Also Removed 2nd parameter of _GetDate_fromUnixTime() which was unnecessary.
1 person likes this

My Contributions: Unix Timestamp: Calculate Unix time, or seconds since Epoch, accounting for your local timezone and daylight savings time. RegEdit Jumper: A Small & Simple interface based on Yashied's Reg Jumper Function, for searching Hives in your registry.  

Share this post


Link to post
Share on other sites



Thanks to FireFox, via a PM, for not only suggesting to include a function to revert a Unix Time to a Date stamp, but providing a very nice example as well.

Func _GetUnixDate($iUnixTime, $blTrim = True)
    Local $aRet = 0, $aDate = 0
    Local $aMonthNumberAbbrev[13] = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
    Local $aSysTimeInfo = _Date_Time_GetTimeZoneInformation()

    $aRet = DllCall("msvcrt.dll", "str:cdecl", "ctime", "int*", $iUnixTime - $aSysTimeInfo[1] * 60)
    If @error Or Not $aRet[0] Then Return ""

    $aDate = StringSplit(StringTrimRight($aRet[0], 1), " ", $STR_NOCOUNT)

    If $blTrim Then Return StringFormat("%.2d", _ArraySearch($aMonthNumberAbbrev, $aDate[1])) & "/" & $aDate[2] & "/" & StringRight($aDate[4], 2) & " " & StringTrimRight($aDate[3], 3)

    Return $aDate[2] & "/" & StringFormat("%.2d", _ArraySearch($aMonthNumberAbbrev, $aDate[1])) & "/" & $aDate[4] & " " & $aDate[3]
EndFunc   ;==>_GetUnixDate

I have also added a parameter to _GetUnixTime($sDate) allowing any date since 1970 to be passed and converted to Unix Time. Leaving the parameter empty or passing zero(0) will convert the current date to Unix Time.

I have also made a few minor changes to the example provide from FireFox.

1. Change the format of the returned string to match the accepted string in function _GetUnixTime()

2. Added another parameter, $iReturnGMT to return the converted time to date in GMT(UTC) or in your current time with consideration to daylight savings time if 'False' is passed in the third parameter.

Thanks again FireFox!

Realm


My Contributions: Unix Timestamp: Calculate Unix time, or seconds since Epoch, accounting for your local timezone and daylight savings time. RegEdit Jumper: A Small & Simple interface based on Yashied's Reg Jumper Function, for searching Hives in your registry.  

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I think I found a bug in the code. The result of _GetDate_fromUnixTime is wrong if the 3rd parameter, $iReturnGMT, is set to False, because the timezone offset is subtracted from the local time, but it should be added instead.

Furthermore, there are several calls to the function _GetUnixDate in the code, but this function was renamed to _GetDate_fromUnixTime, so the calls don't work anymore.

So I created an updated version of Realm's code and added a few comments to it:

#include <Date.au3>
#include <Array.au3>
#include <Constants.au3>

Local $iUnixTime1 = _GetUnixTime()

MsgBox($MB_SYSTEMMODAL, 'Seconds Since Jan, 1st, 1970 00:00:00 GMT', $iUnixTime1)

Local $sUnixDate1 = _GetDate_fromUnixTime($iUnixTime1)
MsgBox($MB_SYSTEMMODAL, "", $sUnixDate1)

$sUnixDate1 = _GetDate_fromUnixTime($iUnixTime1, False)
MsgBox($MB_SYSTEMMODAL, "", $sUnixDate1)

$sUnixDate1 = _GetDate_fromUnixTime($iUnixTime1, False, False)
MsgBox($MB_SYSTEMMODAL, "", $sUnixDate1)

Local $iUnixTime2 = _GetUnixTime('2013/01/01 00:00:00')
MsgBox($MB_SYSTEMMODAL, "", $iUnixTime2)

; Get timestamp for input datetime (or current datetime).
Func _GetUnixTime($sDate = 0);Date Format: 2013/01/01 00:00:00 ~ Year/Mo/Da Hr:Mi:Se

    Local $aSysTimeInfo = _Date_Time_GetTimeZoneInformation()
    Local $utcTime = ""

    If Not $sDate Then $sDate = _NowCalc()

    If Int(StringLeft($sDate, 4)) < 1970 Then Return ""

    If $aSysTimeInfo[0] = 2 Then ; if daylight saving time is active
        $utcTime = _DateAdd('n', $aSysTimeInfo[1] + $aSysTimeInfo[7], $sDate) ; account for time zone and daylight saving time
    Else
        $utcTime = _DateAdd('n', $aSysTimeInfo[1], $sDate) ; account for time zone
    EndIf

    Return _DateDiff('s', "1970/01/01 00:00:00", $utcTime)
EndFunc   ;==>_GetUnixTime

;$blTrim: Year in short format and no seconds.
Func _GetDate_fromUnixTime($iUnixTime, $blTrim = True, $iReturnLocal = True)
    Local $aRet = 0, $aDate = 0
    Local $aMonthNumberAbbrev[13] = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
    Local $timeAdj = 0
    If Not $iReturnLocal Then
        Local $aSysTimeInfo = _Date_Time_GetTimeZoneInformation()
        Local $timeAdj = $aSysTimeInfo[1] * 60
        If $aSysTimeInfo[0] = 2 Then $timeAdj += $aSysTimeInfo[7] * 60
    EndIf

    $aRet = DllCall("msvcrt.dll", "str:cdecl", "ctime", "int*", $iUnixTime + $timeAdj )

    If @error Or Not $aRet[0] Then Return ""

    $aDate = StringSplit(StringTrimRight($aRet[0], 1), " ", 2)

    If $blTrim Then Return  StringRight($aDate[4], 2) & "/" & StringFormat("%.2d",_ArraySearch($aMonthNumberAbbrev, $aDate[1])) & "/" & $aDate[2] & " " & StringTrimRight($aDate[3], 3)

    Return $aDate[4] & "/" & StringFormat("%.2d", _ArraySearch($aMonthNumberAbbrev, $aDate[1])) & "/" & $aDate[2] & " " & $aDate[3]
EndFunc ;==>_GetDate_fromUnixTime

 

Thanks to Realm for creating this useful snippet!

Edited by thegebi
fixed last comment in the code

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Thanks @thegebi,

I have updated my OP including your revision and added some commenting to the MsgBox's to better demonstrate how the functions work.

Edited by Realm
Misspelling.

My Contributions: Unix Timestamp: Calculate Unix time, or seconds since Epoch, accounting for your local timezone and daylight savings time. RegEdit Jumper: A Small & Simple interface based on Yashied's Reg Jumper Function, for searching Hives in your registry.  

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Similar Content

    • Simpel
      By Simpel
      Hi, I created a gui with date field but formatted as time in HH:mm. It always shows "now-time". Even if I try to set it with GUICtrlSetData.
      #include <DateTimeConstants.au3> #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> Example() Func Example() GUICreate("My GUI get date", 200, 200, 800, 200) Local $idDate = GUICtrlCreateDate("", 20, 20, 100, 20, $DTS_TIMEFORMAT) ; to select a specific default format Local $sStyle = "HH:mm" ; Just display hours and minutes <<<<<<<<<<<<<<<<<<<<<<<<<<<< GUICtrlSendMsg($idDate, $DTM_SETFORMATW, 0, $sStyle) ConsoleWrite(GUICtrlRead($idDate) & @CRLF) GUICtrlSetData($idDate, "00:00") ConsoleWrite(GUICtrlRead($idDate) & @CRLF) GUISetState(@SW_SHOW) ; Loop until the user exits. While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd MsgBox($MB_SYSTEMMODAL, "Time", GUICtrlRead($idDate)) EndFunc ;==>Example How can I set the time field with another time and how can this field be set blank?
      Regards, Conrad
    • MyEarth
      By MyEarth
      Hi guys
      I need to get time of different city, London, Jerusalem, Mosca and many others. My starting script:
      #include <Date.au3> Local $iUTC, $iHour, $iMinute, $iSecond $iUTC = _Date_Time_GetSystemTime() $iHour = DllStructGetData($iUTC, "Hour") $iMinute = DllStructGetData($iUTC, "Minute") $iSecond = DllStructGetData($iUTC, "Second") ConsoleWrite("+UTC: " & $iHour & ":" & $iMinute & ":" & $iSecond & @CRLF) My idea was start from UTC time and then add-remove hours. But what about the DST, Daylight Savings Time? How i can know if in a country is active or not? There is an API? Example with _Date_Time_GetTimeZoneInformation it will give the current time zone settings and not for other time zone. I don't have understand if is possible or not 
      On the help i have found SystemTimeToTzSpecificLocalTime but i don't have understand how to use for other time zone...
      Thanks
    • ur
      By ur
      To get the current time stamp, I got the below code.
      #include <Date.au3> #include <MsgBoxConstants.au3> #include <WindowsConstants.au3> #RequireAdmin ; Under Vista the Windows API "SetSystemTime" may be rejected due to system security $td = _Date_Time_GetSystemTime() $td = _Date_Time_SystemTimeToDateTimeStr($td) $td = StringReplace($td, " ", "_") $td = StringReplace($td, ":", "_") MsgBox(0,"",$td) But it is not giving the date or time of the timezone where the system is there.
      Please suggestt
    • Simpel
      By Simpel
      Hi,
      I wanted to use _GetLogonTime() by guinness (https://www.autoitscript.com/forum/topic/19370-autoit-wrappers/?do=findComment&comment=942069).
      #include <Date.au3> #include <Array.au3> ConsoleWrite(_GetLogonTime() & @LF) Func _GetLogonTime($sUserName = @UserName, $sComputerName = @ComputerName) ; Idea by trancexx: http://www.autoitscript.com/forum/topic/113611-if-isadmin-not-detected-as-admin/ Local $aRet = DllCall("netapi32.dll", "long", "NetUserGetInfo", "wstr", $sComputerName, "wstr", $sUserName, "dword", 11, "ptr*", 0) _ArrayDisplay($aRet) If @error Or $aRet[0] Then Return SetError(1, 0, False) Local $sHours = DllStructGetData(DllStructCreate("ptr;ptr;ptr;ptr;dword;dword;dword;ptr;ptr;dword;dword;dword;dword;ptr;dword;ptr;dword;dword;byte;dword", $aRet[4]), 18) DllCall("netapi32.dll", "long", "NetApiBufferFree", "ptr", $aRet[4]) Return _DateAdd("h", "-" & $sHours, _NowCalc()) EndFunc ;==>_GetLogonTime It always returns false.
      I displayed $aRet:
      [0]|2221
      [1]|mycomputer
      [2]|myuser
      [3]|11
      [4]|0x0000000000000000
      $aRet[4] shouldn't be 0x0000000000000000 right? Any help?
      Regards, Conrad