Jump to content

Bug With Getting Time


Recommended Posts

I want to do some calculation base on the current time so I do this

$curHour = @HOUR
$curMin  = @MIN

calcTime($curHour, $curMin)
...

But what if in between my first 2 lines (getting the hour but before the min), the time so happen change from, say, 15:59 to 16:00, then my variables will reflect a time 15:00.

Is there any way to solve this potential bug?

Link to comment
Share on other sites

$timer = TimerInit()

$curHour = @HOUR
$curMin  = @MIN

MsgBox(0, "", TimerDiff($timer)/1000 & " seconds")

I don't think I have to say anything more....

I don't know if _NowTime() will have this "problem" but I don't think you really should care that much about it anyways.

Edited by Pain
Link to comment
Share on other sites

  • Developers

I want to do some calculation base on the current time so I do this

$curHour = @HOUR
$curMin  = @MIN

calcTime($curHour, $curMin)
...

But what if in between my first 2 lines (getting the hour but before the min), the time so happen change from, say, 15:59 to 16:00, then my variables will reflect a time 15:00.

Is there any way to solve this potential bug?

Just curious: did this scenario actually happen to you or is this just a hypothesis?

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • Developers

Hello BruceCopperField,

why didn't you use the UserDefinedFunction _Now, just like this llittle eample

#include <Date.au3>

MsgBox( 4096, "", "Todays date/Time: " & _Now() )

greatings (Auto)Bert

Have you looked what the UDF does?

Why would that be any different?

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Just curious: did this scenario actually happen to you or is this just a hypothesis?

Just a hypothesis. But look, if you have written any multithreaded programs that access a shared variable (say just an int) in multithreaded manner, you can't simply assume the threads won't affect each other because accessing an int involve so minute amount of time. At least, this is the case in Java.

Now the same situation here, unless there is a way to ensure the 2 separate reads are atomic there is still a very low (maybe less than 1/100000, but never 0) chance that the clock is changed in between them.

In other programming languages like C/C++ or Java, we just read the time in 1 single operation (normally fetching a long data type) so we'd never consider this scenario. But it's quite different in AutoIt.

Link to comment
Share on other sites

Run my code and adjust the time to 16:00:00. I used a slow AMD 2GHz to test it and the error appears instantaneously. So to correct my previous post. This isn't an hypothetical issue. It's real. I think AutoIt really need another additional function to fetch the time in a single unit.

Remember to correct your clock after the test.

While True
  $curSS = @SEC
  $curMM = @MIN
  $curHH = @HOUR
  If $curHH = 16 Then 
    If $curMM <> 0 Then
      MsgBox("","","failure: " & $curHH & $curMM & $curSS )
    Else  
      $cmd = "echo 15:59:59 | time"
      RunWait(@ComSpec & " /c " & $cmd, @WorkingDir, @SW_HIDE ) 
    EndIf
  EndIf
WEnd
Link to comment
Share on other sites

... Remember to correct your clock after the test. ...

$cmd = "echo 16:00:00 | time"
RunWait(@ComSpec & " /c " & $cmd, @WorkingDir, @SW_HIDE)

$i = 0

While True
    $i += 1
    $curSS = @SEC
    $curMM = @MIN
    $curHH = @HOUR
    If $curHH = 16 Then
        If $curMM <> 0 Then
            ConsoleWrite($i & "  failure: " & $curHH & $curMM & $curSS & @CR)
            $i = 0
        Else
            $cmd = "echo 15:59:59 | time"
            RunWait(@ComSpec & " /c " & $cmd, @WorkingDir, @SW_HIDE)
        EndIf
    EndIf
WEnd
MS Virtual PCs have problems running code like this.

One fix for that is mentioned here:

http://blogs.msdn.com/virtual_pc_guy/archi...al-pc-2007.aspx

[size="1"][font="Arial"].[u].[/u][/font][/size]

Link to comment
Share on other sites

You can find collision like this (let it run):

While 1

    $iSec1 = @SEC
    $iSec2 = @SEC

    If Not ($iSec2 = $iSec1) Then
        MsgBox(4096, "Collision", "Sec2 = " & $iSec2 & @CRLF & "Sec1 = " & $iSec1 & "                    ")
        Exit
    EndIf

    Sleep(0)

WEnd

If you are really scared then determine your variables this way maybe:

While 1

    $curMin1 = @MIN
    $curHour = @HOUR
    $curMin = @MIN

    If $curMin = $curMin1 Then ExitLoop

WEnd

calcTime($curHour, $curMin)
...

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

(AutoBert @ Jun 1 2009, 10:42 PM)

Hello BruceCopperField,

why didn't you use the UserDefinedFunction _Now, just like this llittle eample

CODE#include <Date.au3>

MsgBox( 4096, "", "Todays date/Time: " & _Now() )

greatings (Auto)Bert

Have you looked what the UDF does?

Why would that be any different?

Jos

This was only a general question, but he can use _Now together with StringRight and StringSplit resulting an array of the actual time:

#include <Date.au3> 
$aNow = StringSplit(StringRight(_Now(),8),":")
MsgBox( 4096, "", "Hours: " & $aNow[1]  & " Minutes: " & $aNow[2] & " Seconds: " & $aNow[3])

(Auto)Bert

Edited by AutoBert
Link to comment
Share on other sites

I think it would generally be unsafe to get the value of the current time between 5 over the hour and 5 before the hour. That's why I have written this script:

; wait for a safe moment to get the time
While @MIN < 5 OR @MIN > 55
    Sleep(1000)
    ; wait for it .. wait for it ..
WEnd

; GO!!!!
$curHour = @HOUR
$curMin  = @MIN
Link to comment
Share on other sites

Why not just get it in a single hit then? You have choice of system time or local time. Return is an array from which you can "pick out the bits".

; $aRet[0] = Year
; $aRet[1] = Month
; $aRet[2] = Day of week
; $aRet[3] = Day
; $aRet[4] = Hour
; $aRet[5] = Minute
; $aRet[6] = Second
; $aRet[7] = Milliseconds
Func _WinAPI_GetCurrentTime($fLocal)
    Local $aRet[8]
    Local $SystemTime = DllStructCreate("ushort;ushort;ushort;ushort;ushort;ushort;ushort;ushort")
    If $fLocal Then
        DllCall("kernel32.dll", "none", "GetLocalTime", "ptr", DllStructGetPtr($SystemTime))
    Else
        DllCall("kernel32.dll", "none", "GetSystemTime", "ptr", DllStructGetPtr($SystemTime))
    EndIf
    For $i = 1 To 8
        $aRet[$i - 1] = DllStructGetData($SystemTime, $i)
    Next
    Return $aRet
EndFunc

WBD

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...