Page 1 of 1

FormatMilliseconds()

Posted: Wed Apr 15, 2009 11:29 am
by nco2k
would be useful:

Code: Select all

Debug FormatMilliseconds("your pc is running since %dd days, %hh hours, %ii minutes and %ss seconds", ElapsedMilliseconds())

Time = ElapsedMilliseconds()
;do stuff
Time = ElapsedMilliseconds() - Time
Debug FormatMilliseconds("time needed for operation, %ii:%ss", Time)
c ya,
nco2k

Posted: Wed Apr 15, 2009 11:43 am
by Guimauve
I fully agree with you this can be very usefull command. This is the command I have created a long time ago for this purpose.

Sorry for the french comment...

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : FormatMilliseconds
; File : Lib_FormatMilliseconds.pb
; File Version : 1.0.0
; Programmation : OK
; Programmed by : Guimauve
; Date : 15-04-2009
; Last Update : 15-04-2009
; Coded for PureBasic V4.30
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Conversion de milliseconde vers en j : H : M : S : Ms <<<<<

ProcedureDLL.s FormatMilliseconds(mask.s, MilliSeconds.l)
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< On fait l'extraction des jours, Heures, minutes, secondes et des MS <<<<<
  
  If MilliSeconds < 0 
    MilliSeconds = MilliSeconds * -1
  EndIf 
  
  Days = MilliSeconds / 86400000 
  MilliSeconds % 86400000
  
  Hours = MilliSeconds / 3600000
  MilliSeconds % 3600000
  
  Minutes = MilliSeconds / 60000
  MilliSeconds % 60000
  
  Seconds = MilliSeconds / 1000
  MilliSeconds % 1000
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< On s'occupe du filtre de sortie <<<<<
  
  If FindString(mask, "%dd", 1)
    
    mask = ReplaceString(mask,"%dd", RSet(Str(Days), 2, "0"))
    
  EndIf 
  
  If FindString(mask, "%hh", 1)
    
    mask = ReplaceString(mask,"%hh", RSet(Str(Hours), 2, "0"))
    
  EndIf 
  
  If FindString(mask, "%mm", 1)
    
    mask = ReplaceString(mask,"%mm", RSet(Str(Minutes), 2, "0"))
    
  EndIf 
  
  If FindString(mask, "%ss", 1)
    
    mask = ReplaceString(mask,"%ss", RSet(Str(Seconds), 2, "0"))
    
  EndIf 
  
  If FindString(mask, "%mss", 1)
    
    mask = ReplaceString(mask,"%mss", RSet(Str(MilliSeconds), 3, "0"))
    
  EndIf
  
  If FindString(mask, "%ms", 1)
    
    mask = ReplaceString(mask,"%ms", RSet(Str(MilliSeconds), 2, "0"))
    
  EndIf 
  
  ProcedureReturn mask
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Regards
Guimauve

Posted: Wed Apr 15, 2009 1:48 pm
by Kaeru Gaman
@Guimauve

Code: Select all

  If MilliSeconds < 0
    MilliSeconds = MilliSeconds * -1
  EndIf 
sorry, this is wrong!

better use

Code: Select all

MilliSeconds.q = ElapsedMilliseconds() & $FFFFFFFF
reason:
it's an unsigned Long, that means when reaching the top value of a signed long, it switches to the maximal negative value.
use a Quad container and the bitwise and to eliminate the sign.

with your method, the clock will be counting down on the second half....

Posted: Thu Apr 16, 2009 2:02 am
by Guimauve
@Kaeru Gaman

This function is a part of my old Lib shown here : http://www.purebasic.fr/english/viewtopic.php?t=18456

If you check carefully I have a Chronometer but also a Temporizer. For the Chonometer there is no problem of negative time but it's not the case with the Temporizer. Sorry but your trick just don't work.

Code: Select all

MilliSeconds.q = ElapsedMilliseconds() 
Temp.q = MilliSeconds & $FFFFFFFF
Debug Temp
MilliSeconds2.q = -1 * Temp
Debug MilliSeconds2 & $FFFFFFFF
Regards
Guimauve

Posted: Thu Apr 16, 2009 4:28 pm
by Kaeru Gaman
you are making a serious mistake there.

Code: Select all

MilliSeconds.q = ElapsedMilliseconds()
Temp.q = MilliSeconds & $FFFFFFFF 
passing the returnvalue to a Quad will cause the sign to be placed in bit63, not in bit 31, so the bitwise and will NOT eliminate the sign.

you need to put an unsigned Long into a LONG.
this will result in a negative value when the highest bit is set.
then you can transfer this value into a Quad using & $FFFFFFFF,
this will interprete bit31 as value not as sign, this is what you want.

so, your code needs to be changed to:

Code: Select all

MilliSeconds.l = ElapsedMilliseconds()
Temp.q = MilliSeconds & $FFFFFFFF 

Posted: Tue Apr 28, 2009 6:52 pm
by Rescator
I'd never use ms for this as it is limited to 49.7 days, after that it wraps around.

Use Date() instead and track the time yourself.

One "trick" is to find out how long smss.exe has been running, as that is the first usermode process started by the OS/kernel.

You could also peek at the system pagefile modified date, which might be the most accurate and easiest method to find this out.

Code: Select all

EnableExplicit

Procedure.s CalculateDays(startdate.i,enddate.i)
 Protected result$,seconds.i,minutes.i,hours.i,days.i
 seconds=enddate-startdate
 If seconds<>0
  minutes=seconds/60 : seconds-(minutes*60)
  hours=minutes/60 : minutes-(hours*60)
  days=hours/24 : hours-(days*24)
  If days>0
   result$=StrU(days,#PB_Long)+" day"
   If Not days=1
    result$+"s "
   Else
    result$+" "
   EndIf
  EndIf
  result$+RSet(StrU(hours,#PB_Long),2,"0")+":"
  result$+RSet(StrU(minutes,#PB_Long),2,"0")+":"
  result$+RSet(StrU(seconds,#PB_Long),2,"0")
 EndIf
 ProcedureReturn result$
EndProcedure



Define old_date.l,old_ms.l,new_date.l

old_date=Date()
Delay(1000)
new_date=Date()

Debug "Your PC has been running for "+CalculateDays(old_date,new_date)+" hours."


;We'll fake a old date here.
Debug "Your PC has been running for "+CalculateDays(old_date-10000000,new_date)+" hours."

new_date=Date()
old_date=new_date-(ElapsedMilliseconds()*0.001)
Debug "Your PC has been running for "+CalculateDays(old_date,new_date)+" hours."

old_date=GetFileDate("C:\pagefile.sys",#PB_Date_Modified)
new_date=Date()
Debug "Your PC has been running for "+CalculateDays(old_date,new_date)+" hours."
[/quote]

Posted: Tue Apr 28, 2009 10:04 pm
by nco2k
Rescator wrote:I'd never use ms for this as it is limited to 49.7 days, after that it wraps around.
you can easily detect that wrap and adjust the timer:

Code: Select all

EnableExplicit
Define TimeLast.q, TimeCurrent.q, TimeElapsed.q

TimeLast = timeGetTime_() & $FFFFFFFF

;...

TimeCurrent = timeGetTime_() & $FFFFFFFF

If TimeCurrent < TimeLast; timer started from zero again
  TimeLast = TimeLast - #MAXDWORD; lets adjust the timer then
EndIf

TimeElapsed = TimeCurrent - TimeLast
c ya,
nco2k

Posted: Tue May 05, 2009 7:04 pm
by Rescator
That is assuming the tool runs constantly.
Using the pagefile modified date can be done whenever, no need to run the tool 24/7.