DateTimeとTimeSpanをWindows PowerShellであれこれ
書き始めた時はWindows PowerShellで時刻と時間をあれこれだったのですが、記事を書きあげてみたらWindows PowerShellがあんまり関係ない話になっていました
この記事は DateTime、TimeSpan、TimeZoneInfo、CultureInfoを知っている人には不要です
- DateTime 構造体 (System).aspx)
- TimeSpan 構造体 (System).aspx)
- TimeZoneInfo クラス (System).aspx)
- CultureInfo クラス (System.Globalization).aspx)
WindowsPowerShell (というか.NETで) 時間に関するデータを扱う場合、時刻 (特定の日時) ならDiteTimeを、時間 (時刻から時刻の間) ならTimeSpanはを使います
Windows PowerShell でDiteTimeのオブジェクトを作る場合、他のオブジェクト同様にNew
からも作れますが、文字列や数値からの変換でも作ることが出来ます
数値を与えた場合、Ticks (1/10,000,000秒、西暦1年1月1日午前0時からの経過時間) として扱われます
PS> [DateTime]::New(2017,1,2,3,4,5) 2017年1月2日 3:04:05 PS> [DateTime]'2017/6/7 8:9:10' 2017年6月7日 8:09:10 PS> [DateTime]10000000 0001年1月1日 0:00:01
TimeSpan型も同様にNew
や数値からも作れます (DateTime同様 Ticks として扱われます) が、DateTimeオブジェクト同士を減算するとTimeSpanオブジェクトが戻り値になります
ちなみに、DateTimeオブジェクトにTimeSpanオブジェクトを加算または減算するとDateTimeオブジェクトになります
PS> [TimeSpan]10000000; Days : 0 Hours : 0 Minutes : 0 Seconds : 1 Milliseconds : 0 Ticks : 10000000 TotalDays : 1.15740740740741E-05 TotalHours : 0.000277777777777778 TotalMinutes : 0.0166666666666667 TotalSeconds : 1 TotalMilliseconds : 1000 PS> [DateTime] '2017/1/1' - [TimeSpan]::New(10,0,0,0); 2016年12月22日 0:00:00 PS> [DateTime]'2017/12/1 12:0:0+05:00' - [DateTime] '2017/1/1 1:10:30-09:00'; Days : 333 Hours : 20 Minutes : 49 Seconds : 30 Milliseconds : 0 Ticks : 288461700000000 TotalDays : 333.867708333333 TotalHours : 8012.825 TotalMinutes : 480769.5 TotalSeconds : 28846170 TotalMilliseconds : 28846170000
Windows PowerShellでこれらを扱う場合、DateTimeオブジェクトとTimeSpanオブジェクトはそれぞれGet-Date
コマンドレット、New-TimeSpan
コマンドレットでも生成できます
Get-Date
コマンドレットはパラメータなしで実行すると現在時刻が設定され、[DateTime]::Now
と同じになります
Get-Date
には.NETのStrings.Formatと同じ形式で出力される形式を指定できる-Format
パラメータ、UNIXのdateのフォーマットと同じ書式で出力される形式を指定できる-UFormat
があります
-Format
の場合、ToString
で同様の処理ができますが、-UFormat
を使いたい場合、Get-Date
を使うことになります
PS> ([DateTime] '2017/12/1 15:0:0+09:00').ToString('yyyy年MM月dd日 (dddd) HH時mm分ss秒'); 2017年12月01日 (金曜日) 15時00分00秒 PS> Get-Date -Date '2017/12/1 15:0:0+09:00' -Format 'yyyy年MM月dd日 (dddd) HH時mm分ss秒'; 2017年12月01日 (金曜日) 15時00分00秒 PS> Get-Date -Date '2017/12/1 15:0:0+09:00' -UFormat '%Y年%m月%d (%A) %H時%M分%S秒' 2017年12月01日 (金曜日) 15時00分00秒
ここまでの例では世界標準時との時差が自動的に9時間に補正されていたり、曜日の表記が日本語になっていますが、これは実行環境に依存した値です
まず、時差を決定しているタイムゾーンの情報については [TimeZoneInfo]::Local
で現在のシステムのタイムゾーンを取得できます
時差はBaseUtcOffset
プロパティから取得でき、TimeSpan型です
PS> >[TimeZoneInfo]::Local; Id : Tokyo Standard Time DisplayName : (UTC+09:00) 大阪、札幌、東京 StandardName : 東京 (標準時) DaylightName : 東京 (夏時間) BaseUtcOffset : 09:00:00 SupportsDaylightSavingTime : False PS> [System.TimeZoneInfo]::Local.BaseUtcOffset.GetType().Name; TimeSpan
タイムゾーンIDでDateTimeを別の時間帯の時刻に変換することもできます
タイムゾーンIDは[TimeZoneInfo]::GetSystemTimeZones()
により全てのタイムゾーンを取得できるのでそこから調べる事ができます
また、[TimeZoneInfo]::FindSystemTimeZoneById
を用いて、IdからTimeZoneInfoを得ることもできます
PS> [TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([DateTime]'2017/12/1 15:00:00+09:00', 'Eastern Standard Time'); 2017年12月1日 1:00:00 [TimeZoneInfo]::FindSystemTimeZoneById('Eastern Standard Time'); Id : Eastern Standard Time DisplayName : (UTC-05:00) 東部標準時 (米国およびカナダ) StandardName : 東部標準時 DaylightName : 東部夏時間 BaseUtcOffset : -05:00:00 SupportsDaylightSavingTime : True
一方、2017/12/1の曜日を
上記の例で2017/12/1の曜日が金曜日と日本語で出力されていたのはが、実行した環境のCultureInfoが日本 ('ja-JP '
)だからで、例えば2017/12/1の曜日を "金曜日" でなく 英語 (米国) 表記で "Friday" と得たい場合、'en-US'
を設定したカルチャ情報を指定することで実現できます
PS> [CultureInfo]::CurrentCulture; LCID Name DisplayName ---- ---- ----------- 1041 ja-JP 日本語 (日本) PS> [CultureInfo]::new('en-US'); LCID Name DisplayName ---- ---- ----------- 1033 en-US 英語 (米国) PS> ([DateTime] '2017/12/1').ToString('dddd', [CultureInfo]::new('en-US')); Friday
カルチャ情報に結び付けられた日付の表記情報についてはDateTimeFormat
プロパティを参照してみてください
そんな感じで一つ