Jump to content

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


Realm
 Share

Recommended Posts

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.

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. 

Link to comment
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. 

Link to comment
Share on other sites

  • 3 years later...

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
Link to comment
Share on other sites

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. 

Link to comment
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
 Share

×
×
  • Create New...