Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Windows] boot_time gives an incorrect result #2094

Open
kernelbug opened this issue Apr 10, 2022 · 2 comments
Open

[Windows] boot_time gives an incorrect result #2094

kernelbug opened this issue Apr 10, 2022 · 2 comments
Labels

Comments

@kernelbug
Copy link

Greetings!

I have noticed that sometimes (frequently enough) boot_time gives a result which corresponds to a time point before the system reboot.

Consider the following commands in cmd.exe:

C:\>wevtutil qe system /c:1 /rd:true /f:text "/q:*[System [(EventID=6013)]]"
Event[0]:
  Log Name: System
  Source: EventLog
  Date: 2022-04-10T12:00:00.043
  Event ID: 6013
  Task: N/A
  Level: Information
  Opcode: N/A
  Keyword: Classic
  User: N/A
  User Name: N/A
  Computer: kernelbug
  Description:
The system uptime is 2345864 seconds.


C:\>C:\Python37\python.exe -c "import datetime;import psutil;print(datetime.datetime.fromtimestamp(psutil.boot_time()))"
2022-03-14 08:21:55.244493

Event ID 6013 corresponds to Windows uptime event which is logged right after the event service startup and every 24h providing seconds since boot.
Thus we can calculate the actual boot time:

>>> import dateutil.parser
>>> uptime_event_time =  dateutil.parser.parse("2022-04-10T12:00:00.043")
>>> actual_boot_time = uptime_event_time - datetime.timedelta(seconds=2345864)
>>> print(actual_boot_time)
2022-03-14 08:22:16.043000

which is consistent with taskmgr's uptime and is inconsistent with boot_time's result.

Moreover, I have checked Windows Event log, and there is an event approximately corresponding to the timestamp given by boot_time. Here is a brief exposure of this event:

<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
...
<EventID Qualifiers="16384">7036</EventID> 
...
<TimeCreated SystemTime="2022-03-14T05:21:55.381383600Z" /> 
...
</System>
<EventData>
<Data Name="param1">WMI Performance Adapter</Data> 
<Data Name="param2">stopped</Data> 
...
</EventData>
</Event>

Therefore OS was still running (and btw was shutting down) at that moment.

I would like to stress that it is nothing more than a coincidence, still it highlights the fact that boot_time result is incorrect and corresponds to a pre-boot time of the system.

Environment info:

Microsoft Windows Server 2019 == 10.0.17763.2686
python == 3.7.9
psutil == 5.7.2
@kernelbug
Copy link
Author

One could use this workaround, maybe:

import ctypes
import datetime
import sys

def boot_time() -> float:
    assert sys.platform == "win32"
    ctypes.windll.kernel32.GetTickCount64.restype = ctypes.c_ulonglong
    milliseconds_since_boot = ctypes.windll.kernel32.GetTickCount64()
    current_time = datetime.datetime.now()
    boot_time = current_time - datetime.timedelta(milliseconds=milliseconds_since_boot)
    return boot_time.timestamp()

@kernelbug kernelbug changed the title boot_time gives an incorrect result on Windows [Windows] boot_time gives an incorrect result Apr 14, 2022
@dbwiddis
Copy link
Contributor

dbwiddis commented May 8, 2022

Windows doesn't provide accurate boot time in any of its API functions. Essentially they don't handle hibernate/sleep time well and the event log is the only "accurate" way of getting the boot time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants