Dsmoeg999 Posted March 31, 2023 Posted March 31, 2023 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)
Danp2 Posted March 31, 2023 Posted March 31, 2023 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 Latest Webdriver UDF Release Webdriver Wiki FAQs
Dsmoeg999 Posted March 31, 2023 Author Posted March 31, 2023 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)
water Posted March 31, 2023 Posted March 31, 2023 (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 March 31, 2023 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
Dsmoeg999 Posted March 31, 2023 Author Posted March 31, 2023 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 ")
Danp2 Posted March 31, 2023 Posted March 31, 2023 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 ") Latest Webdriver UDF Release Webdriver Wiki FAQs
water Posted March 31, 2023 Posted March 31, 2023 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
mistersquirrle Posted March 31, 2023 Posted March 31, 2023 (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 April 2, 2023 by mistersquirrle We ought not to misbehave, but we should look as though we could.
Dsmoeg999 Posted April 2, 2023 Author Posted April 2, 2023 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 mistersquirrle Posted April 2, 2023 Solution Posted April 2, 2023 (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: expandcollapse popupGlobal $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 April 2, 2023 by mistersquirrle Dsmoeg999 1 We ought not to misbehave, but we should look as though we could.
Dsmoeg999 Posted April 2, 2023 Author Posted April 2, 2023 (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 April 2, 2023 by Dsmoeg999
AutoBert Posted April 3, 2023 Posted April 3, 2023 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
mistersquirrle Posted April 3, 2023 Posted April 3, 2023 (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 April 3, 2023 by mistersquirrle Updated times for fairer comparison We ought not to misbehave, but we should look as though we could.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now