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

カルチャが異なる場合のDateクラスのToStringメソッド結果がSQL文で使えない

環境/言語:[Windows7 VB.net]
分類:[.NET]

いつもお世話になっております。

DateクラスのTostringメソッドが使えない状況に出くわし、
解決策を考えています。

状況としては、OSの地域と言語(すなわちアプリのメインのスレッドのカルチャ)が
 ドイツ語(ドイツ)や英語(英国)だった場合、ToStringメソッドが

  2.1.2014
や
  2/1/2014

を返して来ます。ここで問題になるのが、VBソース内にあるベタ書きSQL文にて、
これらが含まれてしまった場合、DB側でエラーになることです。
 DB側は en-US や ja-JP でのTostring結果: 2014/1/2 なら
受け入れるようです。(おそらくDBの照合順序が
JAPANESE_CI_AI であるのと関係があるかも知れません。)

そこで、カルチャに依存しない、DateクラスからのSQL文に適合した
文字列への変換が無いものかと考えたのですが、Dateクラス自身には
そのようなメソッドは無いように見え、自作の関数で解決すること
にしました。

ここで悩ましいのですが、以下の2つのどちらで行こうかということです。

    Public Function DATE_EN_US(ByVal d As Date) As String

        System.Threading.Thread.CurrentThread.CurrentCulture = Globalization.CultureInfo.GetCultureInfo("en-US")
        Dim t As String = d.ToShortDateString
        System.Threading.Thread.CurrentThread.CurrentCulture = Globalization.CultureInfo.GetCultureInfo([アプリ起動時のカルチャ])
        Return t

    End Function

    Public Function DATE_EN_US_2(ByVal d As Date) As String

        Return  d.Year.ToString + "/"  +  d.Month.ToString + "/" + d.Day.ToString 

    End Function


前者は、カルチャの一時的変更、後者は文字列連結です。
 この関数は極めて高頻度で呼び出されるので、カルチャの変更というのを、そう
頻繁に行っていいのか、という不安があります。
 また、この関数はグローバル展開する業務アプリのフレームワーク的な部分に
なってくるので、上の二つのうちより良い方を、もしくは第三のやり方があるのなら
それに決めたい、という背景があります。

宜しくお願いします。

※SQLClientのSQLCommandにパラメータで代入する、というやり方は度外視します。
すでに大量のベタ書きSQLがソース内にあり、それら全てのパラメータ付きSQL文への
リファクタリングは今から考えられないためです。
■No32125に返信(kane123さんの記事)
> そこで、カルチャに依存しない、DateクラスからのSQL文に適合した
> 文字列への変換が無いものかと考えたのですが、Dateクラス自身には
> そのようなメソッドは無いように見え、自作の関数で解決すること
> にしました。

DateTime.ToStringで可能ですよ。
MSDN: DateTime.ToString メソッド (String)
http://msdn.microsoft.com/ja-jp/library/zdtaw1bw(v=vs.110).aspx

・"o"を使う
MSDN: 標準の日付と時刻の書式指定文字列#ラウンドトリップ ("O"、"o") 書式指定子
http://msdn.microsoft.com/ja-jp/library/az4se3k1(v=vs.110).aspx#Roundtrip
・カスタムの形式を使う
MSDN: カスタムの日付と時刻の書式指定文字列
http://msdn.microsoft.com/ja-jp/library/8kb3ddd4(v=vs.110).aspx

等,方法はいくつかありますが,日付を特定の書式で出力する方法は用意されています。
ありがとうございます。
大変助かりました。

最後にもう一点お教えいただけると幸いなのですが、

http://dobon.net/vb/dotnet/string/datetimeformat.html 
を参照すると、

書式指定子 "O" は 
「ISO 8601に準拠しており、カルチャに依存しない
.NET Framework 2.0以降でサポート」

とあります。
これがDecimalでも同じようなカルチャに依存しない書式指定子は
存在しないのでしょうか?

例えば、ドイツでは、
Dim dec As Decimal = 1200.345
をTostring または Tostring("F")しても
桁区切りが 1.200,345

となります。
解決済み!
■No32125に返信(kane123さんの記事)
> DateクラスのTostringメソッドが使えない状況に出くわし、
> 解決策を考えています。
細かいことを言うと、
VBの日付型(Date)は、"Date クラス" ではなく "DateTime クラス" で、
そのメソッドは "Tostring" ではなく "ToString" ですが、それはさておき。


> ドイツ語(ドイツ)や英語(英国)だった場合、ToStringメソッドが
たとえ日本語であったとしても、設定次第では「和暦」が返されますので、
この手の文字列への(あるいは文字列からの)変換においては、
数値にしろ日付にしろ、「書式」と「カルチャ」の両方を
明示的に指定するべきだと思っています。

自分の場合は、中立カルチャを使いますね。

Dim s As String = dt.ToString("yyyy\/MM\/dd", CultureInfo.InvariantCulture)


画面表示などにおいては、あえてユーザー設定のカルチャで表示するような
場合もありますが、大抵の場合は、そのアプリケーションで決めたカルチャ書式で
統一する方が都合が良いので、常に書式を指定するようにしています。
魔界の仮面弁士さん、ありがとうございます。

お教えいただいた方法で行こうと思います。

現在、OSの言語設定を様々に変えながら検証していますが、
Decimal にしても、 DateTime にしても

 ToString("G", CultureInfo.InvariantCulture)

で共通化してSQL文に適合した中立的な文字列への変換が
できそうです。

大変役に立ちました。ありがとうございました。


>VBの日付型(Date)は、"Date クラス" ではなく "DateTime クラス" で、
>そのメソッドは "Tostring" ではなく "ToString" ですが、それはさておき。

気をつけます。ご指摘ありがとうございます。

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