Jump to content

Recommended Posts

Hello!

I'm wondering how safe it is to use AutoIT built-in date and time macros like @HOUR, @MIN etc.

Let's say my script is:

$val = @HOUR
ConsoleWrite($val & @CRLF)
$val = @MIN
ConsoleWrite($val & @CRLF)
$val = @SEC
ConsoleWrite($val & @CRLF)

and I run the script at 19:59:59.

Am I right that it is possible that the script may print values 19, 00 and 00?

If so, then how should I modify the script so that I could always get correct time?

Link to post
Share on other sites

In your example AutoIt adds 1 to @SEC and @MIN but not to @HOUR. I would consider this to be a bug.
I'm sure that after 19:59:59 you will get 20:00:00.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2021-06-05 - Version 1.5.4.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (NEW 2021-06-14 - Version 1.6.5.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (NEW 2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites
6 minutes ago, water said:

I'm sure that after 19:59:59 you will get 20:00:00.

Sorry to say you are not right.  It will always depends when each statements are executed.  Best approach is to get full time at once. There is multiple ways to reach this goal.

Link to post
Share on other sites
40 minutes ago, EskoFIN said:

I'm wondering

Exit ConsoleWrite(TimeNow() & @CRLF)
Func TimeNow( $iReturnArray = 0 )
    Local $aArray[8] = [7]
    Do
        $aArray[7] = @MSEC
        $aArray[6] = @SEC
        $aArray[5] = @MIN
        $aArray[4] = @HOUR
        $aArray[3] = @MDAY
        $aArray[2] = @MON
        $aArray[1] = @YEAR
    Until $aArray[6] = @SEC
    If $iReturnArray Then Return $aArray
    Return $aArray[1] & "-" & $aArray[2] & "-" & $aArray[3] & "_" & $aArray[4] & ":" & $aArray[5] & ":" & $aArray[6] & "." & $aArray[7]
EndFunc

..now your time, is the time that of that time. :D

Link to post
Share on other sites
16 minutes ago, argumentum said:
Exit ConsoleWrite(TimeNow() & @CRLF)
Func TimeNow( $iReturnArray = 0 )
    Local $aArray[8] = [7]
    Do
        $aArray[7] = @MSEC
        $aArray[6] = @SEC
        $aArray[5] = @MIN
        $aArray[4] = @HOUR
        $aArray[3] = @MDAY
        $aArray[2] = @MON
        $aArray[1] = @YEAR
    Until $aArray[6] = @SEC
    If $iReturnArray Then Return $aArray
    Return $aArray[1] & "-" & $aArray[2] & "-" & $aArray[3] & "_" & $aArray[4] & ":" & $aArray[5] & ":" & $aArray[6] & "." & $aArray[7]
EndFunc

..now your time, is the time that of that time. :D

Thanks! Clever solution!

Link to post
Share on other sites
36 minutes ago, argumentum said:
#include <Date.au3>
#include <MsgBoxConstants.au3>
MsgBox($MB_SYSTEMMODAL, "", "Todays date/Time: " & _Now())

He joined in 2011. We'd guess he don't wanna use what's there but is unsure. I don't know.:huh2:

This I don't understand. If my script is not foolproof then this should not be either? This is _Now function:

Func _Now()
    Return _DateTimeFormat(@YEAR & "/" & @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC, 0)
EndFunc   ;==>_Now

 

Link to post
Share on other sites
28 minutes ago, EskoFIN said:

If my script is not foolproof then this should not be either?

Exit ConsoleWrite('>>>' & TimeNow() & @CRLF)
Func TimeNow( $iReturnArray = 0 )
    Local $aArray[8] = [7]
    Do
        $aArray[6] = @SEC ; first instance/query
        $aArray[7] = @MSEC
        $aArray[5] = @MIN
        $aArray[4] = @HOUR
        $aArray[3] = @MDAY
        $aArray[2] = @MON
        $aArray[1] = @YEAR
    Until $aArray[6] = @SEC ; if first instance still true, then that's that
    If $iReturnArray Then Return $aArray
    Return $aArray[1] & "-" & $aArray[2] & "-" & $aArray[3] & "_" & $aArray[4] & ":" & $aArray[5] & ":" & $aArray[6] & "." & $aArray[7]
EndFunc

Then this code above is the best to make sure that the time within that second, is the that it was within that second.
I mean, within that second of yyyy/mm/dd hh:mm:ss is that was at that second. This should be foolproof.

Link to post
Share on other sites
Posted (edited)
2 hours ago, EskoFIN said:

how safe it is to use AutoIT built-in date and time macros

@EskoFIN As you suspect, it is NOT safe to use the date time macros in critical applications, because the system time could click over a minute, an hour, a day or even a year between calls to the macros.
What you are looking for is _NowCalc(). Returns the current Date and Time in format YYYY/MM/DD HH:MM:SS.

This is what @Nine alluded to.

Here's a complex example of use taken directly from the help file

#include <Date.au3>
#include <MsgBoxConstants.au3>

; Calculated the number of seconds since EPOCH (1970/01/01 00:00:00)
Local $iDateCalc = _DateDiff('s', "1970/01/01 00:00:00", _NowCalc())
MsgBox($MB_SYSTEMMODAL, "", "Number of seconds since EPOCH: " & $iDateCalc)

; Calculated the number of Hours this year
$iDateCalc = _DateDiff('h', @YEAR & "/01/01 00:00:00", _NowCalc())
MsgBox($MB_SYSTEMMODAL, "", "Number of Hours this year: " & $iDateCalc)

 

Edited by pseakins
wording. Credited Nine

Phil Seakins

Link to post
Share on other sites
Posted (edited)

What @Nine may have meant is something like this:

#include <Date.au3>
Exit NowTestThis()
Func NowTestThis()
    Local $tLocalTime = _Date_Time_GetLocalTime()

    ; ...so you can get the date/time right out of the struct
    ConsoleWrite( _
        $tLocalTime.Year      & @TAB & @SEC & ':' & @MSEC & @CRLF & _
        $tLocalTime.Month     & @TAB & @SEC & ':' & @MSEC & @CRLF & _
        $tLocalTime.Day       & @TAB & @SEC & ':' & @MSEC & @CRLF & _
        $tLocalTime.Hour      & @TAB & @SEC & ':' & @MSEC & @CRLF & _
        $tLocalTime.Minute    & @TAB & @SEC & ':' & @MSEC & @CRLF & _
        $tLocalTime.Second    & @TAB & @SEC & ':' & @MSEC & @CRLF & _
        $tLocalTime.MSeconds  & @TAB & @SEC & ':' & @MSEC & @CRLF)
EndFunc

Edit #5 ? :..going down the rabbit hole: So yes, it can happen that a time difference occur, as in deeper testing in a slow PC, it showed to change 1 ms. while processing, therefore, that could be the ms. of ... end of the hour?/day?/year?, so the assurance to get a timestamp is important. So either use a function to make sure that that second is the same from first macro call to the last macro call or something like the above function, that gets the "GetLocalTime" from kernel32.dll as a Struct.

PS: .. just learned something today, I never looked deep into :thumbsup: 

Edited by argumentum
oops
Link to post
Share on other sites
8 hours ago, pseakins said:

@EskoFIN As you suspect, it is NOT safe to use the date time macros in critical applications, because the system time could click over a minute, an hour, a day or even a year between calls to the macros.
What you are looking for is _NowCalc(). Returns the current Date and Time in format YYYY/MM/DD HH:MM:SS.

This is what @Nine alluded to.

Here's a complex example of use taken directly from the help file

#include <Date.au3>
#include <MsgBoxConstants.au3>

; Calculated the number of seconds since EPOCH (1970/01/01 00:00:00)
Local $iDateCalc = _DateDiff('s', "1970/01/01 00:00:00", _NowCalc())
MsgBox($MB_SYSTEMMODAL, "", "Number of seconds since EPOCH: " & $iDateCalc)

; Calculated the number of Hours this year
$iDateCalc = _DateDiff('h', @YEAR & "/01/01 00:00:00", _NowCalc())
MsgBox($MB_SYSTEMMODAL, "", "Number of Hours this year: " & $iDateCalc)

 

I don't understand how _NowCalc solves the problem:

Func _NowCalc()
    Return @YEAR & "/" & @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC
EndFunc   ;==>_NowCalc

Those 6 macro calls may sometimes be out of "sync", right? Because, as we have learned by now, and you said it by yourself, those macros are not executed at the same time.

Link to post
Share on other sites

The problem is that the execution of a statement generally takes time. During this process, seconds, minutes, etc. can skip to the next unit. This takes longer with scripting languages than with compiled languages. The question for all languages is therefore not how to prevent this problem, but what frequency of "incorrect" results you can accept. AutoIt is certainly unsuitable for real-time processing.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2021-06-05 - Version 1.5.4.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (NEW 2021-06-14 - Version 1.6.5.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (NEW 2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites
8 hours ago, argumentum said:

What @Nine may have meant is something like this:

#include <Date.au3>
Exit NowTestThis()
Func NowTestThis()
    Local $tLocalTime = _Date_Time_GetLocalTime()

    ; ...so you can get the date/time right out of the struct
    ConsoleWrite( _
        $tLocalTime.Year      & @TAB & @SEC & ':' & @MSEC & @CRLF & _
        $tLocalTime.Month     & @TAB & @SEC & ':' & @MSEC & @CRLF & _
        $tLocalTime.Day       & @TAB & @SEC & ':' & @MSEC & @CRLF & _
        $tLocalTime.Hour      & @TAB & @SEC & ':' & @MSEC & @CRLF & _
        $tLocalTime.Minute    & @TAB & @SEC & ':' & @MSEC & @CRLF & _
        $tLocalTime.Second    & @TAB & @SEC & ':' & @MSEC & @CRLF & _
        $tLocalTime.MSeconds  & @TAB & @SEC & ':' & @MSEC & @CRLF)
EndFunc

Edit #5 ? :..going down the rabbit hole: So yes, it can happen that a time difference occur, as in deeper testing in a slow PC, it showed to change 1 ms. while processing, therefore, that could be the ms. of ... end of the hour?/day?/year?, so the assurance to get a timestamp is important. So either use a function to make sure that that second is the same from first macro call to the last macro call or something like the above function, that gets the "GetLocalTime" from kernel32.dll as a Struct.

PS: .. just learned something today, I never looked deep into :thumbsup: 

Thanks, _Date_Time_GetLocalTime looks like the most elegant solution so far!

Link to post
Share on other sites
5 hours ago, EskoFIN said:

I don't understand how _NowCalc solves the problem

You're right, it doesn't.

I assumed _NowCalc was a system call which would take care of the possible issues, I didn't look at its source. _Date_Time_GetLocalTime looks like it may offer the solution which I hoped I was pointing you to. Thanks to @argumentum for digging a little deeper. Once again I failed to follow my own advice which is "never assume".

Phil Seakins

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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...