DateTimeを使って特定の時刻を表す
これに対して、特定の時刻を表すには、DateTimeオブジェクトを使う。DateTimeも.NET Frameworkのオブジェクトである。
●DateTime
https://docs.microsoft.com/ja-jp/dotnet/api/system.datetime?view=netframework-4.8
PowerShellでは、Get-DateコマンドなどがDateTimeオブジェクトを返す。Windowsが起動した時刻は、Get-CimInstanceコマンドを使い、
(Get-CimInstance Win32_OperatingSystem).LastBootUpTime
で得られる。これもDateTimeオブジェクトだ。

Windowsが記録した起動日時は、Get-CimInstanceコマンド(gcimと略すこともできる)で求めることができる。これは時刻なので、現在時刻を表す(Get-Date)から引き算すると時間(TimeSpan)となり、書式設定などが可能
そのため、現在時刻を表すGet-Dateから再起動した時刻を引けば、経過時間を得ることができる。なお、Get-CimInstanceはgcimというエイリアスが標準で定義されている。
(Get-Date) - (gcim Win32_OperatingSystem).LastBootUpTime
上記の引き算の左右はともにDateTimeオブジェクト(時刻)なので、その結果はTimeSpan(時間)になる。先頭のGet-Dateにカッコが必要なのは、Get-Dateの値をここで計算させるためだ。これがないと後続の部分が式ではなくGet-Dateコマンドの引数とみなされてエラーになってしまう。このあたりがPowerShellのわかりにくく面倒なところだろう。
同様に現在時刻から、再起動後の経過時間を引けば、起動時刻を求めることができる。この結果は時刻なのでDateTimeである。
(Get-Date) - [TimeSpan][int64](1E4*[Environment]::TickCount)

現在時刻からTickCountによる稼働時間を引けば、起動日時を計算できる。ただし、TickCountには誤差が含まれるのと、カウントの開始タイミングにより、LastBootUpTimeとはズレがある
ただし、上記の計算結果は、記録された時間である“LastBootUpTime”とは数秒の誤差がある。というのも、TickCountはシステムタイマーの割り込みを使ってソフトウェアで合算していくもので、ミリ秒単位の誤差を含むからだ。もっともWindowsが起動した時間や経過時間を秒単位で確定することはあまりないので概算値でも問題はないだろう。
Unix/Linux形式の時刻表現を変換する
Windowsのアプリケーションでも、一部のプログラムはUnix/Linux形式の時刻表現を使う。Unix/Linuxでは、協定世界時(UTC)で1970年1月1日午前0時0分0秒を起点とした秒数で時刻を表す。これはUnix時間などと呼ばれ、起点となる時刻をUnix Epocという。Linuxのdateコマンドを使うと、現在時刻をUnix時間で表示できる。
date +'%s'
Unix時間は2023年11月14日までは、上位2桁が16の10桁の数値である。このことを知っていると、データ中のUnix時間にアタリをつけることができる。Excelなどで読み込んだファイルの日付データを見たら、「1640962800」のような数字だった場合、Unix時間を使っている可能性が高い。
これをDateTimeに直すには、Unix時間からTimeSpanを作り、Unix Epocに加算してやればよい。Unix EpocはUTCなので、get-dateの引数にUTCの時刻オフセット「+0000」を付ける。時刻は省略すると「0時0分0秒」が仮定されるので省略可能だ。
(get-date -Date '1970/1/1 +0000') + [TimeSpan][Int64](1E7*1640962800)
とする。
整数値からTimeSpanへの変換は結構頻度が高い。なので関数を定義しておくといい。
function global:I2TS($v) {
return [TimeSpan][Int64](Invoke-Expression $v) }
上記の式なら“(get-date -Date '1970/1/1 +0000') + (I2TS 1E7*1640962800)”と書ける(加算記号の両側をカッコでくくる点に注意)。
起動からの経過時間をGUIで見るだけでいいというのであれば、タスクマネージャーのパフォーマンスタブにあるCPUに「稼働時間」というのがある。また、コマンドラインで表示するだけでよいのであれば、systeminfo.exeコマンドがある。とはいえ、PCを使ううえで時間を計算したくなることはある。そんなときにDateTimeとTimeSpanを使ってみるといいだろう。

この連載の記事
-
第469回
PC
Windows Updateの27年 悪役だった頃から改良が進んで、徐々に目立たない存在に -
第468回
PC
2025年のWindowsどうなる!? Windows Insider Programの状況をあらためて見る -
第467回
PC
Copilot+ PCのNPUでカメラを処理する「Windows Studio Effects」 その内容や効果は? -
第466回
PC
PowerToysの最近の新機能には、複数アプリを指定位置に起動する「ワークスペース」や新規作成のカスタマイズがある -
第465回
PC
WindowsのPowerShellからBluetoothデバイスを調べる -
第464回
PC
Windows 10のサポート切れまで1年を切った さてWindows 10マシンをどうする? -
第463回
PC
Windows Terminal Preview版でSixelグラフィックスを実際に表示させてみる -
第462回
PC
Windows Terminal Preview版でSixelグラフィックスを扱う -
第461回
PC
Copilot+ PCを買ってみたが、「今焦って買う必要はない」のかもしれない -
第460回
PC
Windowsでsftpを使う -
第459回
PC
WSL 2.4.4ではtar形式でのディストリビューションが配布でき、企業での利用が容易になってきた - この連載の一覧へ