さまざまなタイムゾーンと夏時間の設定からのグローバル時間データを処理する必要があるアプリケーションを扱っています。アイデアは、すべてをUTC形式で内部的に保存し、ローカライズされたユーザーインターフェイスに対してのみ前後に変換することです。SQL Serverは、時間、国、およびタイムゾーンを指定して翻訳を処理するためのメカニズムを提供しますか?
これは一般的な問題であるに違いないので、グーグルが使用可能なものを何も表示しないことに驚いています。
ポインタはありますか?
さまざまなタイムゾーンと夏時間の設定からのグローバル時間データを処理する必要があるアプリケーションを扱っています。アイデアは、すべてをUTC形式で内部的に保存し、ローカライズされたユーザーインターフェイスに対してのみ前後に変換することです。SQL Serverは、時間、国、およびタイムゾーンを指定して翻訳を処理するためのメカニズムを提供しますか?
これは一般的な問題であるに違いないので、グーグルが使用可能なものを何も表示しないことに驚いています。
ポインタはありますか?
回答:
7年が経過しました...
実際には、必要なことを正確に実行するこの新しいSQL Server2016機能があります。
これはATTIME ZONEと呼ばれ、DST(夏時間)の変更を考慮して日付を指定されたタイムゾーンに変換します。
詳細はこちら:https:
//msdn.microsoft.com/en-us/library/mt612795.aspx
これは、現在SQLServerのホストと同じUTCオフセットを持つ日付に対して機能します。夏時間の変更は考慮されていません。YOUR_DATE
変換するローカル日付に置き換えます。
SELECT DATEADD(second, DATEDIFF(second, GETDATE(), GETUTCDATE()), YOUR_DATE);
これらの回答のいくつかはあなたを球場に連れて行くでしょうが、夏時間のためにSqlServer2005以前の任意の日付でやろうとしていることを行うことはできません。現在のローカルUTCと現在のUTCの差を使用すると、現在のオフセットが得られます。問題の日付のオフセットがどうなるかを判断する方法が見つかりませんでした。
そうは言っても、SqlServer 2008がその問題に対処する可能性のあるいくつかの新しい日付関数を提供することは知っていますが、以前のバージョンを使用している人は制限に注意する必要があります。
私たちのアプローチは、UTCを永続化し、変換の精度をより細かく制御できるクライアント側で変換を実行することです。
SQL Server2016以降およびAzureSQL Databaseの場合は、組み込みAT TIME ZONE
ステートメントを使用します。
SQL Serverの古いエディションの場合、ここにリストされているように、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)
数値オプションは、現地時間の値が夏時間の影響を受ける場合の動作を制御するためのフラグです。これらは、プロジェクトのドキュメントで詳細に説明されています。
SQL Server 2008には、と呼ばれるタイプがありdatetimeoffset
ます。この種のものには本当に便利です。
http://msdn.microsoft.com/en-us/library/bb630289.aspx
次に、この関数SWITCHOFFSET
を使用して、あるタイムゾーンから別のタイムゾーンに移動しますが、UTC値は同じままです。
http://msdn.microsoft.com/en-us/library/bb677244.aspx
ロブ
あるゾーン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 ZONE
SQL Server 2016以降でのみ機能し、特定のタイムゾーンに変換するときに自動的に昼光を考慮するという利点があります
AT TIME ZONE
呼び出し(フレーズ?)を一緒にチェーンできることを示しているという事実以外の理由がなければ、私はこれが大好きです!単にエレガント。先ほどstackoverflow.com/a/44579178/112764が私のニーズを満たしていると言いましたが、これはさらに優れています。主な称賛。
DECLARE @UTCDateTime DATETIME = GETUTCDATE();
DECLARE @ConvertedZoneDateTime DATETIME;
-- 'UTC' to 'India Standard Time' to 'Eastern Standard Time' DATETIME
SET @ConvertedZoneDateTime = @UTCDateTime AT TIME ZONE 'UTC' AT TIME ZONE 'India Standard Time' AT TIME ZONE 'Eastern Standard Time'
SELECT @UTCDateTime AS UTCDATE,@ConvertedZoneDateTime AS EasternStandardTime
はい、複数のAT TIME ZONE
通話を連鎖させることができますが 、変換にはFromとToで十分であり、必要なものはほとんどです
私は、ローカルイベント(例:会議/パーティーなど、美術館での午後12時から午後3時)に関係のないすべての日時ストレージにDateTimeOffsetを使用する傾向があります。
現在の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;
};
}
使用例:
SELECT
Getdate=GETDATE()
,SysDateTimeOffset=SYSDATETIMEOFFSET()
,SWITCHOFFSET=SWITCHOFFSET(SYSDATETIMEOFFSET(),0)
,GetutcDate=GETUTCDATE()
GO
戻り値:
Getdate SysDateTimeOffset SWITCHOFFSET GetutcDate
2013-12-06 15:54:55.373 2013-12-06 15:54:55.3765498 -08:00 2013-12-06 23:54:55.3765498 +00:00 2013-12-06 23:54:55.373