18

DateTime 列と、過去 3 年間のさまざまな日付 (現地時間の PST 値) の約 10 万行を含む SQL テーブルがある場合、これらの列の値をDateTimeOffsetに移行して、欠落している utc tz オフセット情報を「追加」する最善の戦略は何ですか?

既存の DateTime 値は、タイム ゾーン/UTC オフセットの詳細なしで格納されています。格納される日付は常に太平洋標準時 (夏時間に応じて -800 または -700) を表します。目標は、日付が太平洋時間からのものであるという前提で、既存のすべてのデータに tz オフセットをさかのぼって追加することです (日付によって指定された時点での正しいオフセットが何であれ)。

  • SQL 内で、データを失うことなく、または既存の値を変更することなく、このタイプの移行のベスト プラクティスは何ですか?

  • 次のステップに進むと、中程度のサイズのデータ​​ベース全体 (テーブルごとに 2 つの DateTime 列を含む ~100 個のテーブルで ~100GB) を移行して DateTimeOffset 列と値を使用する最も効率的な方法は何ですか?

  • PST/PDT 切り替え日の午前 2 時前後に記録された日時はどうなりますか? 発生するデータ損失はありますか?

SQL Server 2008 + C# 4.5

これが適切な領域でない場合は、正しい方向に私を向けてください、ありがとう!

編集:やった、バウンティタイム。

4

2 に答える 2

6

夏時間は常に正確な科学ではありません。たとえば、2007 年に北米で使用される期間の規則が変更されました。このため、テーブルに関連する日付を入力することをお勧めします。例: 2000-2013:

-- Populate a table with PST daylight saving start/end times
-- Example data for 2000-2013 - sourced from
-- http://www.timeanddate.com/worldclock/timezone.html?n=137
CREATE TABLE dst (start DateTime, [end] DateTime);
INSERT INTO dst (start, [end]) VALUES ('02:00 2 Apr 2000', '02:00 29 Oct 2000');
INSERT INTO dst (start, [end]) VALUES ('02:00 1 Apr 2001', '02:00 28 Oct 2001');
INSERT INTO dst (start, [end]) VALUES ('02:00 7 Apr 2002', '02:00 27 Oct 2002');
INSERT INTO dst (start, [end]) VALUES ('02:00 6 Apr 2003', '02:00 26 Oct 2003');
INSERT INTO dst (start, [end]) VALUES ('02:00 4 Apr 2004', '02:00 31 Oct 2004');
INSERT INTO dst (start, [end]) VALUES ('02:00 3 Apr 2005', '02:00 30 Oct 2005');
INSERT INTO dst (start, [end]) VALUES ('02:00 2 Apr 2006', '02:00 29 Oct 2006');
INSERT INTO dst (start, [end]) VALUES ('02:00 11 Apr 2007', '02:00 4 Oct 2007');
INSERT INTO dst (start, [end]) VALUES ('02:00 9 Apr 2008', '02:00 2 Nov 2008');
INSERT INTO dst (start, [end]) VALUES ('02:00 8 Apr 2009', '02:00 1 Nov 2009');
INSERT INTO dst (start, [end]) VALUES ('02:00 14 Apr 2010', '02:00 7 Nov 2010');
INSERT INTO dst (start, [end]) VALUES ('02:00 13 Apr 2011', '02:00 6 Nov 2011');
INSERT INTO dst (start, [end]) VALUES ('02:00 11 Apr 2012', '02:00 4 Nov 2012');
INSERT INTO dst (start, [end]) VALUES ('02:00 10 Apr 2013', '02:00 3 Nov 2013');

もちろん、これよりも多くのことが必要になるかもしれません - それは読者の練習問題として残しておきます :-)

dtでは、上記のテーブルに可能な範囲全体を入力し、テーブルのフィールドに日付/時刻があるとしましょうtest。次に、上記のテーブルに結合して、次のように変換できます。

-- Convert sample dates to PST offset with daylight saving where appropriate
SELECT test.dt,
       CAST(CONVERT(VARCHAR(23), test.dt, 126) + -- Convert to ISO8601 format
            CASE WHEN dst.start IS NULL
                 THEN '-08:00' -- No record joined so not within DST period
                 ELSE '-07:00' -- DST record joined so is within DST period
            END AS DateTimeOffset) AS dto
FROM test
LEFT JOIN dst -- Join on daylight savings table to find out whether DST applies
ON test.dt >= dst.start
AND test.dt <= dst.[end]

ここにSQL フィドルのデモがあります。

于 2013-08-16T22:08:05.663 に答える