更新された回答
元の回答で話したユーティリティ、ここにあります を作成しました。 。
また、SQL Server 2016(およびAzure SQLデータベース)の時点で、AT TIME ZONE
を使用できるようになりました。 タイムゾーン間で変換するキーワード。
元の回答
残念ながら、SQLServerでタイムゾーンを操作するための優れたソリューションはありません。
これ
と一緒にあなたがリンクした問題を徹底的に調査しました また。組み込みのタイムゾーン関数はなく、TimeZoneInfo
を使用することもできます。 SQLCLRでは、アセンブリを「安全でない」として登録する必要があります。これは通常望ましくありません。
また、 NodaTime を使用して調査しました。 SQLCLRから。これについては、この問題 で読むことができます。 。また、特定のアイテムが内部でキャッシュされる方法のため、「安全ではない」として登録する必要がありました。
最終的に、どちらの項目でも、問題はSQLCLRに何もキャッシュする方法がないことです。静的変数をスレッドセーフな方法で使用することはできません。また、スレッドの同期を行ったり、ConcurrentDictionary
などのクラスを使用したりすることはできません。 。 SQLは、アセンブリのスレッドモデルを完全に制御したいと考えています。 「安全な」アセンブリでは、シングルスレッドの1回限りの使用と破棄のスタイルコードのみが機能します。私はこの質問でこれを深く掘り下げました:SQLCLRでのマルチスレッドキャッシング
うまくいけば、最終的に SQLCLRで動作するNodaTimeのビルドですが、キャッシュを行わない特別なビルドになります。そのため、それほど速くは実行されませんが、安全でありながら作業を完了できます。
TimeZoneInfo
変更される可能性はありません。したがって、SQLServerチームがタイムゾーン関数をSQLServerに直接適切に導入しない限り(OracleやPostgresのように)、選択肢はわずかです。
-
データレイヤーでタイムゾーン変換を試みないでください。
datetime
を操作する またはdatetime2
UTCの値、またはdatetimeoffset
を使用します 任意のオフセットを持つ値。ただし、アプリケーション層のタイムゾーン間ですべての変換を行います。これが今のところ私の最善の推奨事項です。 -
タイムゾーンのすべてのデータを実際のSQLテーブルにコピーし、そのデータを処理する関数を記述します。データは頻繁に変更されるため、テーブルのメンテナンスが困難になる可能性があるため、これは最善のアイデアではありません。また、夏時間の変更のすべてのルールを含め、関数を正確にすることは困難な場合があります。これがうまくまとめられているプロジェクトを私は知りませんが、誰かがそうなら-コメントで知らせてください。
-
xp_regread
を有効にする Windowsレジストリキーから直接タイムゾーンデータを操作します。更新は自動的に行われますが、これらの関数を作成する際にも同じ課題があります。また、レジストリ読み取りを有効にすることは、とにかく安全でないCLRアセンブリを有効にすることと同じくらいセキュリティリスクになる可能性があります。
私が検討しているもう1つのアイデアは、 IANA / OlsonTZDB を作成することです。 SQLServer専用のパーサーと関数。これは上記のオプション2と似ていますが、保守可能な方法で、Windowsタイムゾーンの代わりにIANA標準データを使用して実行されます。多分私はいつかこれにたどり着くでしょう、あるいは誰かが私をそれに打ち負かすでしょう。繰り返しになりますが、私はこれを行う現在のプロジェクトを知りませんが、誰かがそれを知っている場合は、コメントで知らせてください。 (完了-上部の更新を参照 )
SWITCHOFFSET
について -これは、ターゲットオフセットがすでにわかっている場合にのみ機能します。それは戦いの半分であり、おそらくMicrosoftがまだdatetimeoffset
をマークしている理由です ドキュメント
では「夏時間対応」ではありません。 。