Jump to content
Tuts 4 You

PureBasic Adventures...

Sign in to follow this  
  • entries
    7
  • comments
    10
  • views
    31,065

System Up-Time Since BootTime...

Teddy Rogers

3,427 views

Last week I read a blog entry by Raymond Chan regarding the way Task Manager computes the systems up-time and it reminded me of a bug I noticed in AID64's implementation. On Sunday I had a bit of free time before the Manchester United vs Arsenal game kicked off and decided to see what I could come up with.

 

There are a dozen different methods for calculating up-time, some methods are better and some of these do factor in leap years. Raymond's particular blog mentioned the use of GetTickCount API (contradictory to what he implies it does include sleep time), that method seems a little long winded if your end result is to format the result in to; years, month, days, hours, minutes and seconds. I'll show you a simpler way by using NtQuerySystemInformation and taking advantage of Windows API time functions. You can also use this method if you want to compute the time between two different dates such as how old someone is, although Windows Calculator has that covered with it's date calculations. Of course the example code below is in PureBasic, if you have queries regarding the code please comment...

 
Declare UpdateSystemTime(void)

If OpenWindow(0, 0, 0, 400, 65, "System Up-Time Since BootTime...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  TextGadget(1, 10, 10, 95, 20, "System Boot Time :")
  TextGadget(2, 105, 10, 200, 20, "")
  
  TextGadget(3, 10, 35, 50, 20, "UpTime :")
  TextGadget(4, 60, 35, 400, 20, "")
  
  CreateThread(@UpdateSystemTime(), #Null)
  
  Repeat
    MyEvent = WaitWindowEvent()
  Until MyEvent = #PB_Event_CloseWindow
  
EndIf

Procedure UpdateSystemTime(void)
  #SystemTimeOfDayInformation = 3
  #STATUS_SUCCESS = 0
  
  Structure SYSTEM_TIMEOFDAY_INFORMATION                ; We are only concerned about BootTime and CurrentTime members of this structure.
    BootTime.FILETIME
    CurrentTime.FILETIME
  EndStructure  
  
  Protected SystemBootTime.SYSTEM_TIMEOFDAY_INFORMATION ; SystemInformation parameter should be large enough to hold an opaque SYSTEM_TIMEOFDAY_INFORMATION structure.
  
  Repeat
    ; Use NtQuerySystemInformation to retrieve BootTime and Current time information. Note "NtQuerySystemInformation may be altered or unavailable in future versions of Windows".
    
    If NtQuerySystemInformation_(#SystemTimeOfDayInformation, @SystemBootTime, SizeOf(SystemBootTime), #Null) = #STATUS_SUCCESS

      ; Subtract the high and low order parts of the file time from LocalTime and BootTime to calculate the time and date difference.
      
      SystemBootTime\CurrentTime\dwLowDateTime - SystemBootTime\BootTime\dwLowDateTime
      SystemBootTime\CurrentTime\dwHighDateTime - SystemBootTime\BootTime\dwHighDateTime 
      
      ; Convert the FILETIME structure into a time that is easy to display to a user.
      
      FileTimeToSystemTime_(@SystemBootTime\BootTime, @lpSystemTime_BootTime.SYSTEMTIME)
      FileTimeToSystemTime_(@SystemBootTime\CurrentTime, @lpSystemTime_CurrentTime.SYSTEMTIME)
      
      ; Convert BootTime time in Coordinated Universal Time (UTC) to local time.
      
      SystemTimeToTzSpecificLocalTime_(#Null, @lpSystemTime_BootTime, @lpSystemTime_BootTime)
      
      ; Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC) - offset from this date.
      
      lpSystemTime_CurrentTime\wYear - 1601
      lpSystemTime_CurrentTime\wMonth - 1
      lpSystemTime_CurrentTime\wDay - 1
      
      ; Display date and time difference as UpTime Since Last Reboot...
      
      SetGadgetText(2, Str(lpSystemTime_BootTime\wDay) + "/" + Str(lpSystemTime_BootTime\wMonth) + "/" + Str(lpSystemTime_BootTime\wYear) + " @ " + Str(lpSystemTime_BootTime\wHour) + ":" + Str(lpSystemTime_BootTime\wMinute) + ":" + Str(lpSystemTime_BootTime\wSecond))
      SetGadgetText(4, Str(lpSystemTime_CurrentTime\wYear) + " years, " + Str(lpSystemTime_CurrentTime\wMonth) + " months, " + Str(lpSystemTime_CurrentTime\wDay) + " days, (" + Str(lpSystemTime_CurrentTime\wHour) + " hours, " + Str(lpSystemTime_CurrentTime\wMinute) + " minutes, " + Str(lpSystemTime_CurrentTime\wSecond) + " seconds)")
      
      ; Cycle once every second...
      
      Sleep_(1000)
      
    Else
      MessageBox_(#Null, "Could not retrieve system information...", "Peanut!", #MB_ICONERROR | #MB_TOPMOST | #MB_SETFOREGROUND)
      Break
    EndIf

  ForEver
  
EndProcedure

 

Ted.

System Up-Time Since BootTime.zip

  • Like 3


2 Comments


Recommended Comments

mrexodia

Posted

You could also use GetTickCount, which gets the number of milliseconds (approximately) since boot time. This will reset after 48 days though, but in that case you could use GetTickCount64.

Nice blog entry though!

Share this comment


Link to comment

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
×