長寿命プロジェクトでのタイムゾーンの導入の詳細

しばらく前、彼らはタイムゾーンのサポートが必要な新しい市場の要件にシステムを適応させ始めました。 以前の記事で説明した初期調査。 現在、現実の影響下でアプローチが少し進化しました。 カットの下で、議論中に遭遇しなければならなかった問題の説明、および実装されている最終的な解決策。



TL; DR







今、克服する困難についてより詳細に。



「刺繍された」標準IT産業



オフセットを使用して現地時間に日付を保存することから人々を救うのにかなり長い時間がかかりました。 しばらく前に、経験のあるプログラマーに「タイムゾーンのサポート方法」を尋ねると、唯一のオプションは「UTCを使用し、ショーの直前に現地時間に変換する」だけでした。 通常の操作では、オフセットやタイムゾーン名などの追加情報が依然として必要であるという事実は、実装の裏に隠れていました。 DateTimeOffsetの出現により、そのような詳細が明らかになりましたが、「プログラミングエクスペリエンス」の慣性により、「UTCからのベースオフセットを使用したローカル日付の保存」はUTCの保存と同じではありません。 どこでもDateTimeOffsetを使用することのもう1つの利点は、.NET FrameworkおよびSQL Serverのタイムゾーンへの準拠の制御を委任することを可能にし、システムからのデータの入力と出力の瞬間だけを人間が制御できるようにします。 人間の制御とは、日付/時刻の値を操作するためにプログラマーによって書かれたコードを意味します。



この恐怖を克服するために、私は説明、例、および概念実証を用いて複数のセッションを実施しなければなりませんでした。 プロジェクトで解決されるタスクに例が単純で近いほど、より良い結果が得られます。 「一般に」議論し始めると、これは理解の複雑化と無駄な時間の浪費につながります。 要するに:理論が少なく、実践が多い。 UTCおよびDateTimeOffsetに対する引数は、次の2つのカテゴリに起因します。





UTCまたはDateTimeOffsetは、ゾーン間の変換規則に関する情報を使用せずにDSTの問題を解決しないことに注意してください。これは、C#のTimeZoneInfoクラスからアクセスできます。



簡易モデル



上記のように、古いコードでは、変更はデータベースでのみ発生します。 これがどのように機能するかは、簡単な例を使用して評価できます。



T-SQLのサンプルモデル
-- 1)   --     ,     declare @input_user1 datetime = '2017-10-27 10:00:00' --        declare @timezoneOffset_user1 varchar(10) = '+03:00' declare @storedValue datetimeoffset --       set @storedValue = TODATETIMEOFFSET(@input_user1, @timezoneOffset_user1) --     select @storedValue 'stored' -- 2)   --   2     declare @timezoneOffset_user2 varchar(10) = '-05:00' --          --           select @storedValue 'stored value', CONVERT(DATETIME, SWITCHOFFSET(@storedValue, @timezoneOffset_user1)) 'user1 Moscow', CONVERT(DATETIME, SWITCHOFFSET(@storedValue, @timezoneOffset_user2)) 'user2 NY' -- 3)  2    declare @input_user2 datetime --     ,      - set @input_user2 = '2017-10-27 02:00:00.000' --      set @storedValue = TODATETIMEOFFSET(@input_user2, @timezoneOffset_user2) select @storedValue 'stored' -- 4)   select @storedValue 'stored value', CONVERT(DATETIME, SWITCHOFFSET(@storedValue, @timezoneOffset_user1)) 'user1 Moscow', CONVERT(DATETIME, SWITCHOFFSET(@storedValue, @timezoneOffset_user2)) 'user2 NY'
      
      







スクリプトの結果は次のようになります。







例からわかるように、このモデルを使用すると、データベースでのみ変更を行うことができ、欠陥のリスクが大幅に削減されます。



日付/時刻値を処理するための関数の例
 --     -   DateTimeOffset   ,    +00:00,     ,     .      DateTime        -- DateTime     DateTimeOffset,          create function fn_ConcatinateWithTimeOffset(@dto datetimeoffset, @userId int) returns DateTimeOffset as begin declare @user_time_zone varchar(10) set @user_time_zone = '-05:00' --    @userId return todatetimeoffset(convert(datetime, @dto), @user_time_zone) end --      DateTimeOffset    DateTime,         ,     DateTime,    create function fn_GetUserDateTime(@dto datetimeoffset, @userId int) returns DateTime as begin declare @user_time_zone varchar(10) set @user_time_zone = '-05:00' --    @userId return convert(datetime, switchoffset(@dto, @user_time_zone)) end
      
      







小さなアーティファクト



SQLコードの適応中に、DateTimeで機能するがDateTimeOffsetと互換性のないものがいくつか発見されました。





結論またはUTC vs DateTimeOffset



UTCのアプローチのように、データを送受信するときに変換に取り組んでいることに気づく人がいるかもしれません。 次に、実績のある実用的なソリューションがあるのに、なぜそれがすべてなのでしょうか? これにはいくつかの理由があります。





これらの理由は、説明されたアプローチを使用するために重要であると思われました。 私は質問に答えて、コメントを書いてうれしいです。



All Articles