TSQL: Wie Ortszeit in UTC konvertieren? (SQL Server 2008)
-
05-07-2019 - |
Frage
Wir arbeiten mit einer Anwendung handelt, die globale Zeitdaten aus verschiedenen Zeitzonen zu handhaben muss und die Sommerzeit-Einstellungen. Die Idee ist, intern alles im UTC-Format zu speichern und nur hin und her für die lokalisierten Benutzeroberflächen konvertieren. Ist der SQL Server alle Mechanismen bieten, um mit den Übersetzungen Umgang eine Zeit gegeben, ein Land und eine Zeitzone?
Das muss ein weit verbreitetes Problem, so dass ich bin überrascht, google aufdrehen nicht nutzbar etwas würde.
Alle Zeiger?
Lösung
7 Jahre vergangen und ...
tatsächlich gibt es diese neue SQL Server 2016 Feature, das genau das, was Sie brauchen.
Es wird AT TIME ZONE genannt und wandelt Datum in eine Zone angegebenen Zeit unter Berücksichtigung DST (Sommerzeit) ändert.
Mehr Infos hier:
https://msdn.microsoft.com/en-us/library/mt612795.aspx
Andere Tipps
Dies funktioniert für Daten, die zur Zeit die gleichen UTC Offset wie SQL Server-Host; es berücksichtigt nicht für Änderungen des Sommers. Ersetzen YOUR_DATE
mit dem lokalen Datum zu konvertieren.
SELECT DATEADD(second, DATEDIFF(second, GETDATE(), GETUTCDATE()), YOUR_DATE);
Während einige dieser Antworten finden Sie im Baseballstadion bekommen, können Sie nicht tun, was Sie versuchen, mit beliebigen Daten für SQL Server 2005 und früheren Zeitersparnis, weil das Tageslicht zu tun. Unter Verwendung der Differenz zwischen dem aktuellen lokalen und aktuellen UTC gibt mir den Offset wie sie heute existiert. Ich habe nicht einen Weg gefunden, um zu bestimmen, was das für den betreffenden Tag gewesen wäre ausgeglichen.
Das heißt, weiß ich, dass SqlServer 2008 einige neue Datumsfunktionen bietet, die dieses Problem beheben, aber Leute eine frühere Version verwenden, müssen sich der Grenzen sein.
Unser Ansatz ist UTC bestehen bleiben und die Umwandlung auf der Client-Seite durchführt, wo wir mehr Kontrolle über die Umwandlung der Genauigkeit haben.
SQL Server 2008 hat einen Typ namens datetimeoffset
. Es ist wirklich nützlich für diese Art von Sachen.
http://msdn.microsoft.com/en-us/library /bb630289.aspx
Dann können Sie die Funktion SWITCHOFFSET
verwenden, um sie von einer Zeitzone in einer anderen zu verschieben, aber immer noch den gleichen UTC Wert zu halten.
http://msdn.microsoft.com/en-us/library /bb677244.aspx
Rob
Sie können meinen SQL Server Zeitzonen-Unterstützung Projekt zu konvertieren zwischen IANA Standardzeitzonen, as hier aufgeführt.
UTC Local ist wie folgt:
SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'America/Los_Angeles')
Lokal zu UTC ist wie folgt:
SELECT Tzdb.LocalToUtc('2015-07-01 00:00:00', 'America/Los_Angeles', 1, 1)
Die numerischen Optionen sind Flag, das Verhalten zu steuern, wenn die lokalen Zeitwert von Sommerzeit betroffen sind. Diese sind im Einzelnen in der Projektdokumentation beschrieben.
Hier ist der Code einer Zone DateTime
in einer anderen Zone 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
Hinweis : AT TIME ZONE
funktioniert nur auf SQL Server 2016 + und der Vorteil ist, dass es automatisch hält Daylight , wenn auf eine bestimmte Zeitzone konvertieren
Ich neige dazu, für alle Datum Zeitspeicher zu verwenden Datetime anlehnen, die nicht zu einem lokalen Ereignisse stehen. (ZB: Treffen / Party, etc, 12.00 bis 15.00 Uhr im Museum)
Um den aktuellen DTO als UTC zu erhalten:
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]
Hinweis: Ich werde immer UTC verwenden, wenn sie über den Draht ... clientseitige JS Versenden kann auf einfache Weise erhalten / von lokalen UTC. Siehe: new Date().toJSON()
...
Die folgenden JS behandelt ein UTC / GMT Datum in ISO8601-Format zu einem lokalen Datetime-Parsing.
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;
};
}
Ja, bis zu einem gewissen Grad als detaillierten hier .
Der Ansatz, den ich verwendet habe (pre-2008) ist die Umwandlung in .NET Business-Logik zu tun, bevor sie in die DB einfügen.
Sie können GETUTCDATE () Funktion verwenden UTC Datetime zu erhalten Wahrscheinlich können Sie wählen Unterschied zwischen GETUTCDATE () und GETDATE () und diese Differenz verwenden, um Ihre Daten zu UTC ajust
Aber ich mit früheren Nachricht zustimmen, dass es viel einfacher ist richtig Datetime in der Business-Schicht zu steuern (in .NET, zum Beispiel).
Verwendungsbeispiel:
SELECT
Getdate=GETDATE()
,SysDateTimeOffset=SYSDATETIMEOFFSET()
,SWITCHOFFSET=SWITCHOFFSET(SYSDATETIMEOFFSET(),0)
,GetutcDate=GETUTCDATE()
GO
Returns:
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