DOBON.NET DOBON.NETプログラミング掲示板過去ログ

文字列から日付型の変換

環境/言語:[windows server 2003, C#, .NET framework 3.5]
分類:[ASP.NET]

お世話になります。

IIS上で動作するASP.NETのアプリなのですが、
以下のように、文字列から日付型へ変換していました。

@ DateTime.ParseExact("2012/09", "yyyy/MM", null);

日本語OS環境や英語OS環境だと正常に動作するのですが、中国語OS環境で実行するとFormatExceptionが発生してしまいました。
Windowsの地域と言語オプションにある日付の区切り記号を「/」以外へ変えても
日本語や英語OS環境は正常でしたが、中国語OS環境だとエラーになりました。
(中国語でもOSによってはエラーにならなかったりします)

以下のようにすれば、例外とならないことはわかったのですが、
A System.Console.WriteLine(DateTime.ParseExact("2012/09", "yyyy/MM", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None));

@のやりかたで、引数に明示的に書式指定していて、なぜうまくいかないのかが納得がいきません。(MSDN読んでも理由ははっきりと理解できなかったです)


もし、ご存知の方がいらっしゃいましたら、アドバイスいただけないでしょうか。

よろしくお願いします。
2013/08/07(Wed) 23:42:16 編集(投稿者)

■No31739に返信(gourikiさんの記事)
> 以下のように、文字列から日付型へ変換していました。
> @ DateTime.ParseExact("2012/09", "yyyy/MM", null);
null ではなく、明示的に CultureInfo を指定しましょう。

指定するカルチャは、日本の西暦でもInvariantCulture でも
構いませんので、「入力するデータの形式」に合致したものを指定します。


> 日付の区切り記号を「/」以外へ変えても

入力値の日付区切りが常に "/" 書式なのであれば、書式パラメータは
「yyyy/MM」ではなく「yyyy\/MM」とします。

(今回は C# なので、@"yyyy\/MM" あるいは "yyyy\\/MM" ですね)


「/」だと地域設定依存の DateSeparator となりますが
「\/」の場合は常に / という文字を意味します。


なお、"/" でも "-" でも "." でも許容させたいのであれば、
複数の書式を配列で渡すためのオーバーロードもあります。


> 日本語や英語OS環境は正常でしたが、
地域設定が日本でも、日付書式が和暦設定になっていれば、
 DateTime.ParseExact("2012/09", "yyyy/MM", null)
が西暦4000年9月になってしまいますよ。平成2012年という意味で。


> 引数に明示的に書式指定していて、なぜうまくいかないのかが
上記の和暦表示が良い例ですが、カルチャ依存な書式だからです。

地域設定によって、データの入力形式が変化するわけではなく、
常に yyyy/MM 形式(データフォーマットが固定)なのであれば、
システムカルチャに依存した変換処理を行うべきではありません。
データにあわせたカルチャを指定しましょう。
詳しいコメントいただきどうもありがとうございました。


■No31740に返信(魔界の仮面弁士さんの記事)
> 2013/08/07(Wed) 23:42:16 編集(投稿者)
>
> ■No31739に返信(gourikiさんの記事)
> 入力値の日付区切りが常に "/" 書式なのであれば、書式パラメータは
> 「yyyy/MM」ではなく「yyyy\/MM」とします。
>
> (今回は C# なので、@"yyyy\/MM" あるいは "yyyy\\/MM" ですね)
>
>
> 「/」だと地域設定依存の DateSeparator となりますが
> 「\/」の場合は常に / という文字を意味します。

これは知りませんでした!
[/」はDateTimeFormatInfo.DateSeparator プロパティの値で置き換えられるんですね。。
「\/」にしたところうまくいきました。



>>日本語や英語OS環境は正常でしたが、
> 地域設定が日本でも、日付書式が和暦設定になっていれば、
>  DateTime.ParseExact("2012/09", "yyyy/MM", null)
> が西暦4000年9月になってしまいますよ。平成2012年という意味で。

なるほど。こういう問題になってしまうんですね。
コンソールアプリでためしたところ平成2012年になりました。
ただ、ASP.net上ですと和暦でも問題なかったので、configの設定なのでしょうかね。

DOBON.NET | プログラミング道 | プログラミング掲示板