Jump to content

Subtract from a specific time to find out what time it was.


Go to solution Solved by mistersquirrle,

Recommended Posts

Posted

Hi guys, I want to subtract another specific time from a specific time to know what time it was exactly. I have few clues how to do it if you can help me with a simple and brief example it would be appreciated. I show you how I have done it but it doesn't work. Best regards and thank you.

$start = @HOUR == 14 And @MIN == 44 And @SEC == 15
$end = @HOUR == 05 And @MIN == 44 And @SEC == 15

$result=$start-$end

MsgBox(0,"time",$result)

 

Posted

Here's an example using _DateDiff to determine the time between two dates --

#include <Date.au3>

$sStartDate = @YEAR & "/" & @MON & "/" & @MDAY & " " & "05:44:15"
$sEndDate = @YEAR & "/" & @MON & "/" & @MDAY & " " & "14:44:15"

$iElapsedSecs = _DateDiff ("s", $sStartDate, $sEndDate)
MsgBox(4096, "Elapsed Secs", $iElapsedSecs)

$iElapsedHours = _DateDiff ("h", $sStartDate, $sEndDate)
MsgBox(4096, "Elapsed Hours", $iElapsedHours)

HTH, Dan

Posted
1 hour ago, Danp2 said:

Here's an example using _DateDiff to determine the time between two dates --

#include <Date.au3>

$sStartDate = @YEAR & "/" & @MON & "/" & @MDAY & " " & "05:44:15"
$sEndDate = @YEAR & "/" & @MON & "/" & @MDAY & " " & "14:44:15"

$iElapsedSecs = _DateDiff ("s", $sStartDate, $sEndDate)
MsgBox(4096, "Elapsed Secs", $iElapsedSecs)

$iElapsedHours = _DateDiff ("h", $sStartDate, $sEndDate)
MsgBox(4096, "Elapsed Hours", $iElapsedHours)

HTH, Dan

Hello, thank you for your contribution, it helps me to see it better, how could I put also the minutes and show the complete message?

$iElapsedMinutes = _DateDiff ("m", $sStartDate, $sEndDate)
MsgBox(4096, "Elapsed Hours", $iElapsedMinutes)

;Here I try to show the total time

$iElapsedHoursMinutesSecs = _DateDiff ("hms", $sStartDate, $sEndDate)
MsgBox(4096, "Elapsed Total:", $iElapsedHoursMinutesSecs)

 

Posted (edited)

"hms" is invalid. The help file clearly states: "One of the following:"
You either have to call _DateDiff multiple times or you use seconds to calculate all the other needed values (minutes, hours ...)

BTW: Please do not use the "Quote" button to reply to a message. Simply enter your message into the input box (marked with "Reply to this topic") at the end of the thread.

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.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 (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

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

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Posted

Now I understand better how _DateDiff works. I see that it is the individual difference of the hours, minutes and seconds. It would be possible to add more than 60 seconds to minutes and more than 60 minutes to hours. ¿or this way of comparing it would not be a good idea?

What I want to achieve is to show the exact time with hours minutes seconds and with this I get the individual difference of each thing.

MsgBox(4096, "Elapsed Total:", $iElapsedHours&":H "&$iElapsedMinutes&":Min "&$iElapsedSecs&" :Sec ")

 

 

Posted

Use _DateDiff to get the elapsed seconds. Then divide that value by 60 to get the elapsed minutes. Then divide that value by 60 again to get the elapsed hours.

$iElapsedSecs = _DateDiff ("s", $sStartDate, $sEndDate)
$iElapsedMins = $iElapsedSecs / 60
$iElapsedHours = $iElapsedMins / 60

MsgBox(4096, "Elapsed Total:", $iElapsedHours&":H "&$iElapsedMins&":Min "&$iElapsedSecs&" :Sec ")

 

Posted

I get

$iTotalSecs = 3666 ; 1 hour, 1 minute 6 seconds
$iElapsedSecs = Mod($iTotalSecs, 60)
$iElapsedHours = Int ($iTotalSecs / 3600)
$iElapsedMins = Int(Mod($iTotalSecs, 3600)/60)
MsgBox(4096, "Elapsed Total:", $iElapsedHours & " hour, " & $iElapsedMins & " minute(s), " & $iElapsedSecs & " second(s) ")

 

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.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 (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

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

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Posted (edited)

From the original message it sounded to me like you wanted something more like _DateAdd:

Global $sStartDate = @YEAR & "/" & @MON & "/" & @MDAY & " " & "05:44:47"
Global $sEndDate = @YEAR & "/" & @MON & "/" & @MDAY & " " & "14:12:15"

Global $iDifference = _DateDiff('s', $sStartDate, $sEndDate)
ConsoleWrite('$iDifference: ' & $iDifference & @CRLF)

;~ Global $sOldDate = _DateAdd('s', -1 * $iDifference, _NowCalc())
Global $sOldDate = _DateAdd('s', -1 * $iDifference, $sEndDate)
If @error Then
    ConsoleWrite('DateAdd error: ' & @error & ', @extended: ' & @extended & @CRLF)
    EndIf
ConsoleWrite('OldDate: ' & $sOldDate & @CRLF)

From the current messages, here's a function I made for converting MS to a timestamp:

Func __MillisecondToTimestamp($iMs)
    Local $sTimestamp

    $iMs = Int($iMs, 0) ; Auto Int

    ; Convert the milliseconds to days, hours, minutes, and seconds
    $iDays = (($iMs >= 86400000) ? Int($iMs / 86400000) : 0)
    $iHours = Int(Mod($iMs, 86400000) / 3600000)
    $iMinutes = Int(Mod($iMs, 3600000) / 60000)
    $iSeconds = Int(Mod($iMs, 60000) / 1000)

    ; Format the timestamp as [DD ]hh:mm:ss.zzz
    ; Not using StringFormat here because it's considerably slower... when you do it 10K+ times, so probably doesn't matter at all for this
    $sTimestamp = _
            ($iDays > 0 ? StringRight('0' & String($iDays), 2) & ' ' : '') & _
            StringRight('0' & String($iHours), 2) & ':' & _
            StringRight('0' & String($iMinutes), 2) & ':' & _
            StringRight('0' & String($iSeconds), 2) & '.' & _
            StringRight('00' & String($iMs), 3)

    Return $sTimestamp
EndFunc   ;==>__MillisecondToTimestamp

If you only pass in seconds, then you can quickly convert the function to use either: 

$sStartDate = @YEAR & "/" & @MON & "/" & @MDAY & " " & "05:44:47"
$sEndDate = @YEAR & "/" & @MON & "/" & @MDAY & " " & "14:12:15"

Global $iDifference = _DateDiff('s', $sStartDate, $sEndDate)
ConsoleWrite('Seconds difference for comparison: ' & $iDifference & @CRLF)

ConsoleWrite(__MillisecondToTimestamp($iDifference, True) & @CRLF)

Func __MillisecondToTimestamp($iMs, $bSeconds = False)
    Local $sTimestamp

    If $bSeconds Then $iMs *= 1000
    $iMs = Int($iMs, 0) ; Auto Int

    ; Convert the milliseconds to days, hours, minutes, and seconds
    $iDays = (($iMs >= 86400000) ? Int($iMs / 86400000) : 0)
    $iHours = Int(Mod($iMs, 86400000) / 3600000)
    $iMinutes = Int(Mod($iMs, 3600000) / 60000)
    $iSeconds = Int(Mod($iMs, 60000) / 1000)

    ; Format the timestamp as [DD ]hh:mm:ss.zzz
    ; Not using StringFormat here because it's considerably slower... when you do it 10K+ times, so probably doesn't matter at all for this
    $sTimestamp = _
            ($iDays > 0 ? StringRight('0' & String($iDays), 2) & ' ' : '') & _
            StringRight('0' & String($iHours), 2) & ':' & _
            StringRight('0' & String($iMinutes), 2) & ':' & _
            StringRight('0' & String($iSeconds), 2) & _
            ((Not $bSeconds) ? '.' & StringRight('00' & String($iMs), 3) : '')

    Return $sTimestamp
EndFunc   ;==>__MillisecondToTimestamp

 

Edited by mistersquirrle

We ought not to misbehave, but we should look as though we could.

Posted

Hi guys, I have not yet achieved my goal with this question, I am close. I'm sorry but it's still hard for me to understand things, I need more experience I show you two examples so you can see what I mean better. 

;MY CODE AT THE MOMENT

#include <Date.au3>

$sStartDate = @YEAR & "/" & @MON & "/" & @MDAY & " " & "05:44:15"
$sEndDate = @YEAR & "/" & @MON & "/" & @MDAY & " " & "14:44:15"

$iElapsedHours = _DateDiff ("h", $sStartDate, $sEndDate)
MsgBox(4096, "Elapsed Hours", $iElapsedHours)

$iElapsedMins=_DateDiff ("n", $sStartDate, $sEndDate)/60
MsgBox(4096, "Elapsed Minutes", $iElapsedHours)

$iElapsedSecs = _DateDiff ("s", $sStartDate, $sEndDate)/60
MsgBox(4096, "Elapsed Secs", $iElapsedSecs)




MsgBox(4096, "Elapsed Total:", $iElapsedHours&":H "&$iElapsedMins&":Min "&$iElapsedSecs&" :Sec ")

Here are the examples:

14:44:15
05:44:15
----------
 9 H : 0 Min: 0 Sec
 
14:54:45
05:44:15
----------
 9 H : 10 Min: 30 Sec

MsgBox(4096, "Elapsed Total:", $iElapsedHours&":H "&$iElapsedMins&":Min "&$iElapsedSecs&" :Sec ")

 

 

  • Solution
Posted (edited)

Did you try my example? I think that it does what you want. I updated it slightly so that you can use hms as separators for the time instead of colons :.

Here's the updated example:

Global $sStartDate = @YEAR & "/" & @MON & "/" & @MDAY & " " & "05:44:15"
Global $sEndDate = @YEAR & "/" & @MON & "/" & @MDAY & " " & "14:44:15"
Global $iDifference = _DateDiff('s', $sStartDate, $sEndDate)

ConsoleWrite('Seconds difference for comparison: ' & $iDifference & @CRLF)
ConsoleWrite(@TAB & __MillisecondToTimestamp($iDifference, True) & @CRLF)
ConsoleWrite(@TAB & __MillisecondToTimestamp($iDifference, True, False) & @CRLF)

$sStartDate = @YEAR & "/" & @MON & "/" & @MDAY & " " & "05:44:15"
$sEndDate = @YEAR & "/" & @MON & "/" & @MDAY & " " & "14:54:45"
$iDifference = _DateDiff('s', $sStartDate, $sEndDate)

ConsoleWrite('Seconds difference for second comparison: ' & $iDifference & @CRLF)
ConsoleWrite(@TAB & __MillisecondToTimestamp($iDifference, True) & @CRLF)
ConsoleWrite(@TAB & __MillisecondToTimestamp($iDifference, True, False) & @CRLF)

Func __MillisecondToTimestamp($iMs, $bSeconds = False, $bColonSeparator = True)
    Local $sTimestamp

    If $bSeconds Then $iMs *= 1000
    $iMs = Int($iMs, 0) ; Auto Int

    ; Convert the milliseconds to days, hours, minutes, and seconds
    $iDays = (($iMs >= 86400000) ? Int($iMs / 86400000) : 0)
    $iHours = Int(Mod($iMs, 86400000) / 3600000)
    $iMinutes = Int(Mod($iMs, 3600000) / 60000)
    $iSeconds = Int(Mod($iMs, 60000) / 1000)

    ; Format the timestamp as [DD ]hh:mm:ss.zzz
    ; Not using StringFormat here because it's considerably slower... when you do it 10K+ times, so probably doesn't matter at all for this
    $sTimestamp = _
            ($iDays > 0 ? StringRight('0' & String($iDays), 2) & (($bColonSeparator) ? ' ' : 'd') : '') & _
            StringRight('0' & String($iHours), 2) & (($bColonSeparator) ? ':' : 'h') & _
            StringRight('0' & String($iMinutes), 2) & (($bColonSeparator) ? ':' : 'm') & _
            StringRight('0' & String($iSeconds), 2) & _
            ((Not $bSeconds) ? _
            (($bColonSeparator) ? '.' : 's') & StringRight('00' & String($iMs), 3) & (($bColonSeparator) ? '' : 'ms') : _
            (($bColonSeparator) ? '' : 's'))

    Return $sTimestamp
EndFunc   ;==>__MillisecondToTimestamp

And here's the output:

Seconds difference for comparison: 32400
    09:00:00
    09h00m00s
Seconds difference for second comparison: 33030
    09:10:30
    09h10m30s

You can change the separators in the function if you need it to be "H", "Min", "Sec". If you don't want the 0 padding, just change the second param of StringRight from 2 to 1.

Edited by mistersquirrle

We ought not to misbehave, but we should look as though we could.

Posted (edited)

Hi thanks to everyone and especially to mistersquirrle. i want to thank you for helping with this wonderful code. it is better than i expected indeed this is what i was looking for. I still need to understand everything perfectly but it is a step. Best regards

Edited by Dsmoeg999
Posted

I solved this problem this way:

#include <Date.au3>
#AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4

Global $sOrder = 'YMDhns', $sResult

Global $bDebug = True        ;zu Verständniszwecken können Debug Ausgaben angezeigt werden

Global $dtEnd = "2018/10/26 19:03:43"
Global $dtStart = "2009/06/30 14:05:16"
_dtDiff($dtStart, $dtEnd)

Func _dtDiff(ByRef $dtStart, ByRef $dtEnd)
    Local $dtTmp, $sType
    Local $iRes, $sResult
    If $dtStart > $dtEnd Then       ;dtEnd must be the greater one so swaw it
        $dtTmp = $dtStart
        $dtStart = $dtEnd
        $dtEnd = $dtTmp
    EndIf
    For $i = 1 To StringLen($sOrder)
        $sType = StringMid($sOrder, $i, 1)
        $iRes = _Diff_NewStart($dtStart, $dtEnd, $sType)
        $sResult &= $iRes
    Next
    $sResult = StringReplace($sResult, 'n', 'm')
    MsgBox(64, 'Differenz', $sResult, 30)
EndFunc   ;==>_dtDiff

Func _Diff_NewStart(ByRef $dt1, $dt2, $sType)
    Local $iResult = _DateDiff($sType, $dt1, $dt2)
    $dt1 = _DateAdd($sType, $iResult, $dt1) :add the result to the new start date
    If $bDebug Then ConsoleWrite($sType & ': ' & $iResult & @TAB & 'New: ' & $dtStart & @CRLF)
    Return $iResult & $sType & ' '
EndFunc   ;==>_Diff_NewStart

 

Posted (edited)

@AutoBert  That is a neat approach, I like it, though it's quite a bit slower. So if it's something that's going to be called more than a couple times it's going to become a bottleneck. This is with debug off, and _dtDiff returns the $sResult, no consolewrite or msgbox:

Function Times, 10,000 times
 +——————————————————————————+—————————————————+———————————————+——————————————+—————————————+
 |      Function Name       | Time Taken (ms) | Avg Time (ms) | Std Dev (ms) | Faster By % |
 +——————————————————————————+—————————————————+———————————————+——————————————+—————————————+
 | _Launch_dtDiff           |        34774.32 |        3.4774 |       0.4551 |        0.00 |
+| __MillisecondToTimestamp |         3629.31 |        0.3629 |       0.1062 |       89.56 |
 +——————————————————————————+—————————————————+———————————————+——————————————+—————————————+
 |        Total time        |        38403.63 |               |              |             |
 +——————————————————————————+—————————————————+———————————————+——————————————+—————————————+

I also realized with that time range that my function cuts off more than 2 digit days, so I removed that StringRight for this test, so it yielded 3405d04h58m27s.

I also made a wrapper for _dtDiff so that the function didn't destroy the original $dtStart to make sure each function was doing the same thing each run.

Edited by mistersquirrle
Updated times for fairer comparison

We ought not to misbehave, but we should look as though we could.

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...