PowerShellで日付を出力する事は多々あるかと思いますが。
今回はISO 8601の形式で日付を出力する場合について記載します。
本記事で利用している環境
- PowerShell 7.3.2
参考ドキュメント
Standard date and time format strings/
The round-trip ("O", "o") format specifier
Use Culture Information in PowerShell to Format Dates
Convert String to DateTime Object in specific timezone with Powershell
Get-Dateコマンドで現在日付をISO 8601で出力する
Get-Date
コマンドレットは、オプションを付けずに実行すると現在日付を出力します。
Standard date and time format strings/
The round-trip ("O", "o") format specifier
上記、ドキュメントにある通り、Format
オプションにo
を指定すると現在日付をISO 8601の形式で出力してくれます
Get-Date
Get-Date -Format "o"
実行してみると2023-02-21T22:15:46.9472899+09:00
とオフセットが+09:00
で出力されている事がわかります。
これは実行環境が下記のようにTokyo Standard Time
に設定していることに起因します。
Get-Dateコマンドで指定日付をISO 8601で出力する
Get-Date "2023/02/21 09:00:00" -Format "o"
Get-Date
コマンドレットでは文字列を引数として渡すことにより、引数で渡した文字列をパースして[datetime]
を取得する事ができます。
上記のように文字列をパースする場合、Format "o"
と実行すると下記のように2023-02-21T09:00:00.0000000
となり、末尾に+09:00
とオフセットがつきませんでした。
Get-Date
で現在日付を-Format "o"
で出力した場合は、端末の設定を見て、+09:00
となりタイムゾーンが表記されたのに対して。
Get-Date
に文字列で日付を指定しつつFormat o
で出力した場合は、タイムゾーンの表記がなくなりました。
日付指定した場合も同様にオフセットが出力されると予想していましたが、そのような実装にはなっていないようです。
色々と試して見ましたが、下記のようにすれば日付指定した場合でも同様にオフセットを出力できました。
# 一旦、DateTimeOffsetにしてからToStringで出力
([DateTimeOffset](Get-Date "2023/02/21 09:00:00")).ToString("o")
# DateTimeのままToStringで出力するとオフセットはつかない
(Get-Date "2023/02/21 09:00:00").ToString("o")
任意のタイムゾーンに変換してみる
TimeZoneInfo.ConvertTimeBySystemTimeZoneId メソッド
.NETではTimeZoneInfo
のConvertTimeBySystemTimeZoneId
メソッドが用意されており。
これを利用すると変換できます。
Get-Date -Format "o"
(([TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([datetimeoffset]$(Get-Date),"Eastern Standard Time"))).toString("o")
上記例ではローカル時間がJST
の端末で現在時間を、EST
に変換しています。
なお、ConvertTimeBySystemTimeZoneId
メソッドに渡しているID("Eastern Standard Time")については下記コマンドレットで一覧を確認する事ができます。
Get-TimeZone -ListAvailable
ConvertTimeBySystemTimeZoneIdについて補足
TimeZoneInfo.ConvertTimeBySystemTimeZoneId メソッド
色々とためしていて気が付きました。
(([TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([datetimeoffset]$(Get-Date),"Eastern Standard Time"))).toString("o")
(([TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([datetime]$(Get-Date),"Eastern Standard Time"))).toString("o")
上記のように[datetime]
で渡した場合と、[datetimeoffset]
で渡した場合で、オフセット表記に違いがありました。
この違いには見た時にすぐに気が付かなかったのでメモ。
総評
PowerShellで日付処理は.NETが使えると便利かと思います。