it-swarm.com.de

TSQL: Wie konvertiere ich Ortszeit nach UTC? (SQL Server 2008)

Wir haben es mit einer Anwendung zu tun, die globale Zeitdaten aus verschiedenen Zeitzonen und Einstellungen für die Sommerzeit verarbeiten muss. Die Idee ist, alles intern im UTC-Format zu speichern und nur für die lokalisierten Benutzeroberflächen hin und her zu konvertieren. Bietet der SQL Server Mechanismen für den Umgang mit den Übersetzungen zu einer bestimmten Zeit, einem bestimmten Land und einer bestimmten Zeitzone?

Dies muss ein häufiges Problem sein, daher bin ich überrascht, dass Google nichts Verwendbares aufdeckt.

Irgendwelche Hinweise?

68
BuschnicK

7 Jahre vergangen und ...
tatsächlich gibt es diese neue SQL Server 2016-Funktion, die genau das tut, was Sie brauchen.
Es heißt AT TIME ZONE und konvertiert das Datum in eine bestimmte Zeitzone, wobei die Sommerzeit (DST) geändert wird.
Weitere Informationen hier: https://msdn.Microsoft.com/en-us/library/mt612795.aspx

34
Piotr Owsiak

Dies funktioniert für Daten, die derzeit den gleichen UTC-Offset wie der Host von SQL Server haben. Änderungen der Sommerzeit werden nicht berücksichtigt. Ersetzen Sie YOUR_DATE Durch das lokale Datum, das konvertiert werden soll.

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

59
shaig

Mit ein paar dieser Antworten kommen Sie zwar in den Ballpark, Sie können jedoch aufgrund der Sommerzeit nicht mit beliebigen Daten für SqlServer 2005 und frühere Versionen arbeiten. Wenn ich die Differenz zwischen der aktuellen lokalen und der aktuellen UTC nutze, erhalte ich den Offset, wie er heute existiert. Ich habe keine Möglichkeit gefunden, den Offset für das betreffende Datum zu bestimmen.

Trotzdem weiß ich, dass SqlServer 2008 einige neue Datumsfunktionen bietet, mit denen dieses Problem behoben werden kann, aber Benutzer, die eine frühere Version verwenden, müssen sich der Einschränkungen bewusst sein.

Unser Ansatz ist es, UTC beizubehalten und die Konvertierung auf der Clientseite durchzuführen, wo wir mehr Kontrolle über die Genauigkeit der Konvertierung haben.

21
user890155

SQL Server 2008 hat den Typ 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 eine andere zu verschieben, aber den gleichen UTC-Wert beizubehalten.

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

Rauben

14
Rob Farley

Hier ist der Code zum Konvertieren einer Zone DateTime in eine andere 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 ZONEfunktioniert nur auf SQL Server 2016 + und der Vorteil ist, dass es Tageslicht automatisch berücksichtigt beim Konvertieren in eine bestimmte Zeitzone

10
KarthikeyanMlp

Ich tendiere dazu, DateTimeOffset für die Speicherung aller Datums- und Uhrzeitangaben zu verwenden, die nicht mit einem lokalen Ereignis zusammenhängen (z. B. Besprechung/Party usw., 12-15 Uhr im Museum).

So erhalten Sie das aktuelle DTO als 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]

ANMERKUNG: Ich verwende immer UTC, wenn ich über die Leitung sende. Clientseitiges JS kann leicht zu/von lokaler UTC gelangen. Siehe: new Date().toJSON() ...

Die folgende JS verarbeitet das Parsen eines UTC/GMT-Datums im ISO8601-Format auf eine lokale Datumszeit.

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

Ja, bis zu einem gewissen Grad als detailliert hier .
Der Ansatz, den ich (vor 2008) verwendet habe, besteht darin, die Konvertierung in der .NET-Geschäftslogik vor dem Einfügen in die Datenbank durchzuführen.

3
AdaTheDev

Sie können die Funktion GETUTCDATE () verwenden, um die UTC-Datumszeit abzurufen. Möglicherweise können Sie den Unterschied zwischen GETUTCDATE () und GETDATE () auswählen und diesen Unterschied verwenden, um Ihre Datumsangaben auf UTC abzustimmen

Ich stimme jedoch der vorherigen Meldung zu, dass es viel einfacher ist, die richtige Datumszeit in der Business-Schicht zu steuern (z. B. in .NET).

2
Bogdan_Ch