以前、Get-Dateコマンドレットで出力される標準書式について記事を書きました。
PowerShellのGet-Date -Formatで出力される標準の書式指定結果一覧
今回は、PowerShellで[DateTime]型にキャストする際に、PowerShellでのカスタム書式指定についてみていきます。 ====
日付を取得する
繰り返しになりますが、PowerShellで日付を取得する方法をみてみます。
コマンドレットで日付を取得する
まずは、コマンドレットといえばこれです。
Get-Date
何も指定しなければ、本日が取得できます。
2013年2月9日 10:36:09
結果に対して、.AddDays
や.AddMonths
などで対象プロパティを操作もできます。 例えば取得結果から、一日進めるなら…
(Get-Date).AddDays(1)
一日進みました。
2013年2月10日 10:39:13
.Netで日付を取得する
簡単ですね。
[System.DateTime]::Now
これで本日が取得できます。
2013年2月9日 10:41:52
[System.DateTime]
は[DateTime]
に短縮できます。 日付のみを取得するなら、Today
メソッドを利用してこうかけます。
2013年2月9日 0:00:00
文字列を日付型にキャストする
文字列から日付型へのキャスト(型変換)をみてみます。
暗黙の型変換
一つは、「[DateTime]にしなさい」と指定する方法です。 この場合は、PowerShellが[DateTime]型に変換するために理解できる書式である必要があります。 例えばこうです。
[DateTime]"2013/02/09" [DateTime]"2013/02/09 13:59:50"
上手く認識できました。
2013年2月9日 0:00:00 2013年2月9日 13:59:50
では、どこが年月日か不明な場合はどうなるでしょうか。
[DateTime]"20130209"
"文字列は有効な DateTime ではありませんでした。"と怒られてしまいますね。
値 "20130209" を型 "System.DateTime" に変換できません。エラー: "文字列は有効な DateTime ではありませんでした。" 発生場所 D:\Test.ps1:11 文字:1 + [DateTime]"20130209" + ~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) []、RuntimeException + FullyQualifiedErrorId : InvalidCastParseTargetInvocationWithFormatProvider
[System.Datetime]::Parse()メソッドでの型変換
.Netの[System.Datetime]::Parse()
メソッドを利用する方法もあります。 先ほどのコードはこのようになります。
[Datetime]::Parse("2013/02/09") [Datetime]::Parse("2013/02/09 13:59:50")
暗黙の型変換と同様の結果となります。
2013年2月9日 0:00:00 2013年2月9日 13:59:50
こちらも、どこが年月日か不明な場合はどうなるでしょうか。
[Datetime]::Parse(20130209")
怒られますね。
値 "20130209" を型 "System.DateTime" に変換できません。エラー: "文字列は有効な DateTime ではありませんでした。" 発生場所 D:\Test.ps1:11 文字:1 + [DateTime]"20130209" + ~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) []、RuntimeException + FullyQualifiedErrorId : InvalidCastParseTargetInvocationWithFormatProvider
カスタム書式を指定する
では、カスタム日付を指定してみましょう。 まず、カスタム書式を指定するに当たり、何はともあれ知っておきましょう。
カスタムの日付と時刻の書式指定文字列
コマンドレットでカスタム書式を指定する
標準書式と同様に、-Format
で書式を指定できます。 例えばyyyyMMdd_hhmmss
というフォーマットを指定するなら…
Get-Date -Format "yyyyMMdd_HHmmss"
すると指定した書式の[string]型が出力されます。
20130209_105156
つまり、上記の-Format
メソッドを利用した書き方は、.ToString()
メソッドと同等です。
(Get-Date).ToString("yyyyMMdd_HHmmss")
結果も同じですね。
20130209_105156
先ほどの[Datetime]型への変換と、ToString()を組み合わせて、元の文字列の書式を変えることもできますね。 用途があるかは不明ですが。
([DateTime]"2013/02/09 13:59:50").ToString("yyyyMMdd_HHmmss")
結果はこうです。
20130209_135950
.Netでカスタム書式を指定する
[DateTime]::ParseExact()
メソッドを利用します。 MSDNの注意に気を付けましょう。
DateTime.ParseExact メソッド (String, String, IFormatProvider) 指定した書式とカルチャ固有の書式情報を使用して、指定した日付と時刻の文字列形式を等価の DateTime の値に変換します。文字列形式の書式は、指定した書式と完全に一致する必要があります。
例えばこうです。
[DateTime]::ParseExact("12/11/2012 13:59:51","dd/MMM/yyyy HH:mm:ss",$null)
結果は…Systemの国別書式に合わせられていますね。 設定が、日本語(ja-JP)なので年月日となっています。
2012年11月12日 13:59:51
もちろん.ToString()
メソッドで書式指定もできます。
[DateTime]::ParseExact("12/11/2012 13:59:51","dd/MMM/yyyy HH:mm:ss",$null).ToString("dd/MMM/yyyy HH:mm:ss"
指定したとおりになりました。
12/11/2012 13:59:51
[DateTime]::ParseExact利用のメリット
[DateTime]::ParseExact()
であれば、読み取り時に書式にヒントを与えられます。 そのため、コマンドレットや[System.Datetime]::Parse()
よりも柔軟に書式指定ができることがあります。 逆に、指定した書式パターンでないとExcenption(例外)を返すため、曖昧な読み取りも防げます。 例えば、起こられた[DateTime]"20130209"
を読み取らせるには…。
[DateTime]::ParseExact("20130209","yyyyMMdd",$null)
無事に読み取れました。
2013年2月9日 0:00:00
[DateTime]::ParseExact利用時の注意
どうやら、この問題があるようなので注意しましょう。
DateTime.ParseExactメソッドで、1900年代の日時に変換される
テストします。
[DateTime]::ParseExact("301112 13:59:51","yyMMdd HH:mm:ss",[System.Globalization.CultureInfo]::InvariantCulture)
確かに問題ですね…。
1930年11月12日 13:59:51
IFormatProviderで出力するカルチャ指定する
[DateTime]::ParseExact()
を利用する際は、きっちり分かっておく必要がありますね。
IFormatProvider インターフェイス
特に依存を指定しない場合は、IFormatProvider
に[System.Globalization.CultureInfo]::InvariantCulture
を指定します。 これで、カルチャに依存しない (インバリアントな) CultureInfo を取得できます。
CultureInfo.InvariantCulture プロパティ
試してみましょう。
[DateTime]::ParseExact("20121112 13:59:51","yyyyMMdd HH:mm:ss",[System.Globalization.CultureInfo]::InvariantCulture)
さてさて。
2012年11月12日 13:59:51
基本的にPowerShellにおいては、$null
か[System.Globalization.CultureInfo]::InvariantCulture)
を指定しておくことで、現在のスケールで出力されます。
まとめ
PowerShellでのカスタム日付指定は、単純なパターンであれば[DateTime]
で型変換して.ToString()
メソッドで指定にて問題ないかと思います。 が、[DateTime]::ParseExact()
を利用することで、柔軟な読み取りパターン指定ができます。 次回は、[DateTime]::ParseExact()
にて国(Culture)を指定する方法を紹介します。
参考サイト
#PSTip Working with DateTime objects in PowerShell using [System.DateTime] System.DateTime ParseExact