私のローカル開発サーバーは中東にありますが、本番サーバーは英国にあります。
ユーザーにタイムゾーンで日付を表示する必要があります。たとえば、ユーザーがサウジアラビアにいる場合、サウジアラビアの形式に従って時間を表示する必要があります。
TimeZoneという新しいデータベーステーブルを作成し、UTCで時間を保存する必要がありますか?
私のローカル開発サーバーは中東にありますが、本番サーバーは英国にあります。
ユーザーにタイムゾーンで日付を表示する必要があります。たとえば、ユーザーがサウジアラビアにいる場合、サウジアラビアの形式に従って時間を表示する必要があります。
TimeZoneという新しいデータベーステーブルを作成し、UTCで時間を保存する必要がありますか?
回答:
残念ながら、これに対する簡単な修正はありません。アプリケーションの国際化は、日付/時刻の比較や出力のフォーマットなど、さまざまな分野の核心に実際に取り組むため、最初の設計の議論の一部である必要があります。
とにかく、Doing It Rightを追跡するためには、タイムゾーン情報を時間と共に保存することが不可欠です。つまり、(a)タイムゾーンのその時点でのUTCオフセット(注1)を含めるか、(b)これらの値を挿入するすべてのロジックが特定の固定オフセットに最初に変換されることなく、日付/時刻20130407 14:50
が無意味であることを認識します(ほとんどの場合0)。これらのいずれもなければ、与えられた2つの時間値は比較できず、データは破損しています。(後者の方法は、火で遊んでいます(注2)ところで、しないでください。)
SQL Server 2008+では、datetimeoffset
データ型を使用して、オフセットを時間とともに直接保存できます。(完全を期すため、2005年以前は、2番目の列を追加して、その時点でのUTCオフセット値(分単位)を格納します。)
これらのプラットフォームには通常、ユーザーの地域設定に基づいて、日付/時刻+タイムゾーンをローカル時刻に自動的に変換してから出力用にフォーマットするメカニズムが備わっているため、デスクトップタイプのアプリケーションが簡単になります。
本質的に切断されたアーキテクチャであるWebの場合、バックエンドデータが適切に設定されていても、変換やフォーマットを実行できるようにクライアントに関する情報が必要なため、より複雑です。これは通常、ユーザー設定(アプリケーションが出力前に物事を変換/フォーマット)するか、全員に対して同じ固定フォーマットとタイムゾーンオフセットで物事を表示することで行われます(これはStack Exchangeプラットフォームが現在行っていることです)。
バックエンドデータが適切にセットアップされていないと、非常に迅速に複雑でハッキングされることがわかります。最終的にはより多くの問題が発生するため、これらのパスを下ることはお勧めしません。
注1:
タイムゾーンのUTCオフセットは固定されていません。ゾーンのUTCオフセットがプラスまたはマイナス1時間変動する夏時間を考慮してください。また、ゾーンの夏時間は定期的に異なります。だから、使用してdatetimeoffset
(またはの複合local time
とUTC offset at that time
)最大の情報の回復に結果。
注2:
データ入力を制御することです。入ってくる値を検証する確実な方法はありませんが、計算を伴わない単純な標準を実施することをお勧めします。パブリックAPIがオフセットを含むデータ型を予期している場合、その要件は呼び出し元に明確になります。
そうでない場合、呼び出し元はドキュメントに依存する必要があります(ドキュメントを読む場合)、または計算が正しく行われないなど。または、ここの場合のように、別々のサーバー上のWeb /データベースだけでさえも)。
とにかくオフセットを保存すると、1石で2羽の鳥が死にます。そして、それが今必要でなくても、必要であれば後で利用可能になります。確かに、より多くのストレージを使用しますが、そもそも記録しないとデータが失われるため、トレードオフの価値があると思います。
datetimeoffset
「これは、問題が発生したときのユーザー/コンピューターのローカル時間」を意味します-指定されたUTCオフセットが常に存在するため、DSTが有効であったかどうかを知る必要はありません(datetimeoffset
値内に埋め込まれます)。
SQL Serverでのタイムゾーン変換のための包括的なソリューションを開発しました。GitHubでのSQL Serverタイムゾーンサポートを参照してください。
夏時間を含む、タイムゾーン間の変換とUTCとの間の変換を適切に処理します。
これは、adssの回答で説明されている「T-SQL Toolbox」ソリューションに概念的に似ていますが、Microsoftの代わりに、より一般的なIANA / Olson / TZDBタイムゾーンを使用し、データの新しいリリースとして維持されるユーティリティを含みますTZDBが登場します。
使用例(OPに回答するため):
SELECT Tzdb.UtcToLocal(sysutcdatetime(), 'Asia/Riyadh') as CurrentTimeInSaudiArabia
追加のAPIと詳細な説明については、GitHubのreadmeを参照してください。
また、これはUDFベースのソリューションであるため、パフォーマンスを主な目的として設計されていないことに注意してください。この機能がSQL Serverに組み込まれているCONVERT_TZ
と、OracleおよびMySQLに関数がどのように存在するかと同様に、さらに良いでしょう。
SQL Serverは2005年以降、内部タイムゾーンがUTCで保存されるように変更を加えました。これは主に、ジオレプリケーションとログ配布を伴うHAプロジェクターが原因であり、ログ配布時間が異なるタイムゾーンで保存されているため、古い方法では復元できませんでした。
したがって、すべてをUTC時間で内部的に保存することにより、SQL Serverはグローバルに機能します。これは、Outlookなどの他のMS製品も日付/時刻を内部的にUTCとして保存し、修正が必要なオフセットを作成するため、夏時間をWindowsで扱うのが苦痛な理由の1つです。
私は世界中に何千ものサーバー(ただし、MS SQL Serverではなく、あらゆる種類のサーバー)が分散している会社で働いています。非常に迅速に。
SQL Serverで日時とタイムゾーンの処理に苦労している人を支援するために、codeplexで「T-SQL Toolbox」プロジェクトを開発および公開しました。オープンソースであり、完全に無料で使用できます。
簡単な追加の構成テーブルを備えたプレーンなT-SQLを使用して、簡単な日時変換UDFを提供します。
この例では、次のサンプルを使用できます。
SELECT [DateTimeUtil].[UDF_ConvertLocalToLocalByTimezoneIdentifier] (
'GMT Standard Time', -- the original timezone in which your datetime is stored
'Middle East Standard Time', -- the target timezone for your user
'2014-03-30 01:55:00' -- the original datetime you want to convert
)
これにより、ユーザーの変換された日時値が返されます。
サポートされているすべてのタイムゾーンのリストは、T-SQL Toolboxデータベース内でも提供される「DateTimeUtil.Timezone」テーブルにあります。