web-dev-qa-db-ja.com

TSQL:現地時間をUTCに変換する方法は? (SQL Server 2008)

さまざまなタイムゾーンと夏時間の設定からのグローバルな時間データを処理する必要があるアプリケーションを扱っています。アイデアは、すべてを内部的にUTC形式で保存し、ローカライズされたユーザーインターフェイスのみを相互に変換することです。 SQL Serverは、時間、国、タイムゾーンを指定して翻訳を処理するメカニズムを提供しますか?

これは一般的な問題であるに違いないので、グーグルが使用可能なものを何も表示しないことに驚いています。

ポインタはありますか?

68
BuschnicK

7年が経ち...
実際には、必要なことを正確に実行するこの新しいSQL Server 2016機能があります。
これはAT TIME ZONEと呼ばれ、DST(夏時間)の変更を考慮して日付を指定されたタイムゾーンに変換します。
詳細はこちら: https://msdn.Microsoft.com/en-us/library/mt612795.aspx

34
Piotr Owsiak

これは、現在SQL Serverのホストと同じUTCオフセットを持つ日付に対して機能します。夏時間の変更は考慮されません。 YOUR_DATEを変換するローカル日付に置き換えます。

SELECT DATEADD(second, DATEDIFF(second, GETDATE(), GETUTCDATE()), YOUR_DATE);

59
shaig

これらの答えのいくつかはあなたを大まかに導きますが、夏時間のために、SqlServer 2005以前の任意の日付でしようとしていることはできません。現在のローカルと現在のUTCの差を使用すると、今日存在するオフセットが得られます。問題の日付のオフセットがどのようになるかを判断する方法が見つかりませんでした。

そうは言っても、SqlServer 2008にはその問題に対処するいくつかの新しい日付関数が用意されていますが、以前のバージョンを使用しているユーザーは制限に注意する必要があります。

私たちのアプローチは、UTCを保持し、変換の精度をより詳細に制御できるクライアント側で変換を実行することです。

21
user890155

SQL Server 2008にはdatetimeoffsetという型があります。このタイプのものには本当に便利です。

http://msdn.Microsoft.com/en-us/library/bb630289.aspx

次に、関数SWITCHOFFSETを使用して、あるタイムゾーンから別のタイムゾーンに移動しますが、同じUTC値を保持します。

http://msdn.Microsoft.com/en-us/library/bb677244.aspx

ロブ

14
Rob Farley

SQL Serverタイムゾーンサポート プロジェクトを使用して、IANA標準タイムゾーン間で変換することができます ここにリストされているように

ローカルへのUTCは次のようになります。

SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'America/Los_Angeles')

UTCのローカルは次のようになります。

SELECT Tzdb.LocalToUtc('2015-07-01 00:00:00', 'America/Los_Angeles', 1, 1)

数値オプションは、現地時間の値が夏時間の影響を受ける場合の動作を制御するためのフラグです。これらは、プロジェクトのドキュメントで詳細に説明されています。

14

1つのゾーンDateTimeを別のゾーンDateTimeに変換するコードを次に示します

DECLARE @UTCDateTime DATETIME = GETUTCDATE();
DECLARE @ConvertedZoneDateTime DATETIME;

-- 'UTC' to 'India Standard Time' DATETIME
SET @ConvertedZoneDateTime = @UTCDateTime AT TIME ZONE 'UTC' AT TIME ZONE 'India Standard Time'
SELECT @UTCDateTime AS UTCDATE,@ConvertedZoneDateTime AS IndiaStandardTime

-- 'India Standard Time' to 'UTC' DATETIME
SET @UTCDateTime = @ConvertedZoneDateTime AT TIME ZONE 'India Standard Time' AT TIME ZONE 'UTC'
SELECT @ConvertedZoneDateTime AS IndiaStandardTime,@UTCDateTime AS UTCDATE

AT TIME ZONESQL Server 2016+でのみ動作しますと利点は、特定のタイムゾーンに変換するときに自動的にデイライトを考慮します

10
KarthikeyanMlp

私は、ローカルイベントに関連しないすべての日時ストレージにDateTimeOffsetを使用する傾向があります(例:博物館での会議/パーティーなど、午後12時から午後3時まで)。

現在のDTOをUTCとして取得するには:

DECLARE @utcNow DATETIMEOFFSET = CONVERT(DATETIMEOFFSET, SYSUTCDATETIME())
DECLARE @utcToday DATE = CONVERT(DATE, @utcNow);
DECLARE @utcTomorrow DATE = DATEADD(D, 1, @utcNow);
SELECT  @utcToday [today]
        ,@utcTomorrow [tomorrow]
        ,@utcNow [utcNow]

注:有線で送信するときは常にUTCを使用します...クライアント側のJSはローカルUTCに簡単にアクセスできます。参照:new Date().toJSON() ...

次のJSは、ISO8601形式のUTC/GMT日付をローカルの日付時刻に解析します。

if (typeof Date.fromISOString != 'function') {
  //method to handle conversion from an ISO-8601 style string to a Date object
  //  Date.fromISOString("2009-07-03T16:09:45Z")
  //    Fri Jul 03 2009 09:09:45 GMT-0700
  Date.fromISOString = function(input) {
    var date = new Date(input); //EcmaScript5 includes ISO-8601 style parsing
    if (!isNaN(date)) return date;

    //early shorting of invalid input
    if (typeof input !== "string" || input.length < 10 || input.length > 40) return null;

    var iso8601Format = /^(\d{4})-(\d{2})-(\d{2})((([T ](\d{2}):(\d{2})(:(\d{2})(\.(\d{1,12}))?)?)?)?)?([Zz]|([-+])(\d{2})\:?(\d{2}))?$/;

    //normalize input
    var input = input.toString().replace(/^\s+/,'').replace(/\s+$/,'');

    if (!iso8601Format.test(input))
      return null; //invalid format

    var d = input.match(iso8601Format);
    var offset = 0;

    date = new Date(+d[1], +d[2]-1, +d[3], +d[7] || 0, +d[8] || 0, +d[10] || 0, Math.round(+("0." + (d[12] || 0)) * 1000));

    //use specified offset
    if (d[13] == 'Z') offset = 0-date.getTimezoneOffset();
    else if (d[13]) offset = ((parseInt(d[15],10) * 60) + (parseInt(d[16],10)) * ((d[14] == '-') ? 1 : -1)) - date.getTimezoneOffset();

    date.setTime(date.getTime() + (offset * 60000));

    if (date.getTime() <= new Date(-62135571600000).getTime()) // CLR DateTime.MinValue
      return null;

    return date;
  };
}
4
Tracker1

はい、ある程度詳細に こちら です。
私が使用したアプローチ(2008年以前)は、DBに挿入する前に.NETビジネスロジックで変換を行うことです。

3
AdaTheDev

GETUTCDATE()関数を使用してUTC日時を取得できます。おそらく、GETUTCDATE()とGETDATE()の差を選択し、この差を使用して日付をUTCに調整できます。

しかし、ビジネス層(たとえば.NET)で正しい日時を制御する方がはるかに簡単であるという以前のメッセージに同意します。

2
Bogdan_Ch