FormatMilliseconds()

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

FormatMilliseconds()

Post 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
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
User avatar
Guimauve
Enthusiast
Enthusiast
Posts: 742
Joined: Wed Oct 22, 2003 2:51 am
Location: Canada

Post 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
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post 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....
oh... and have a nice day.
User avatar
Guimauve
Enthusiast
Enthusiast
Posts: 742
Joined: Wed Oct 22, 2003 2:51 am
Location: Canada

Post 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
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post 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 
oh... and have a nice day.
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post 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]
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Post 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
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

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