it-swarm.com.de

Konvertieren Sie die Datetime-Spalte von UTC in die Ortszeit in der select-Anweisung

Ich mache ein paar SQL-Select-Abfragen und möchte meine UTC-Datetime-Spalte in Ortszeit konvertieren, um sie als Ortszeit in meinen Abfrageergebnissen anzuzeigen. Bitte beachten Sie, dass ich diese Konvertierung NICHT per Code durchführen möchte, sondern eher manuelle und zufällige SQL-Abfragen für meine Datenbanken.

156
Nugs

Sie können dies auf SQL Server 2008 oder höher wie folgt tun:

SELECT CONVERT(datetime, 
               SWITCHOFFSET(CONVERT(datetimeoffset, 
                                    MyTable.UtcColumn), 
                            DATENAME(TzOffset, SYSDATETIMEOFFSET()))) 
       AS ColumnInLocalTime
FROM MyTable

Sie können auch weniger ausführlich machen:

SELECT DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), MyTable.UtcColumn) 
       AS ColumnInLocalTime
FROM MyTable

Was auch immer Sie tun, verwendet nicht -, um Datumsangaben zu subtrahieren, da die Operation nicht atomar ist und Sie gelegentlich unbestimmte Ergebnisse aufgrund von Race-Bedingungen zwischen der System-Datumszeit und der lokalen Datumszeit erhalten, die zu verschiedenen Zeitpunkten überprüft werden (dh (nicht atomar).

Bitte beachten Sie, dass diese Antwort die DST nicht berücksichtigt. Wenn Sie eine DST-Anpassung hinzufügen möchten, sehen Sie auch die folgende SO - Frage:

So erstellen Sie die Sommerzeit-Start- und Endefunktion in SQL Server

261

Ich fand keines dieser Beispiele hilfreich, um eine als UTC gespeicherte Datumszeit in einer angegebenen Zeitzone (nicht die Zeitzone des Servers) zu speichern, da Azure SQL-Datenbanken als UTC ausgeführt werden. So habe ich es gemacht. Es ist nicht elegant, aber es ist einfach und gibt Ihnen die richtige Antwort, ohne andere Tabellen zu pflegen:

select CONVERT(datetime, SWITCHOFFSET(dateTimeField, DATEPART(TZOFFSET, 
dateTimeField AT TIME ZONE 'Eastern Standard Time')))
26
Aiden Kaskela

Wenn Sie eine andere Konvertierung als den Standort Ihres Servers benötigen, können Sie hier einen Standard-Offset angeben und Konten für die US-Tageszeit sparen:

-- =============================================
-- Author:      Ron Smith
-- Create date: 2013-10-23
-- Description: Converts UTC to DST
--              based on passed Standard offset
-- =============================================
CREATE FUNCTION [dbo].[fn_UTC_to_DST]
(
    @UTC datetime,
    @StandardOffset int
)
RETURNS datetime
AS
BEGIN

    declare 
        @DST datetime,
        @SSM datetime, -- Second Sunday in March
        @FSN datetime  -- First Sunday in November

    -- get DST Range
    set @SSM = datename(year,@UTC) + '0314' 
    set @SSM = dateadd(hour,2,dateadd(day,datepart(dw,@SSM)*-1+1,@SSM))
    set @FSN = datename(year,@UTC) + '1107'
    set @FSN = dateadd(second,-1,dateadd(hour,2,dateadd(day,datepart(dw,@FSN)*-1+1,@FSN)))

    -- add an hour to @StandardOffset if @UTC is in DST range
    if @UTC between @SSM and @FSN
        set @StandardOffset = @StandardOffset + 1

    -- convert to DST
    set @DST = dateadd(hour,@StandardOffset,@UTC)

    -- return converted datetime
    return @DST

END

GO
20
Ron Smith

Verwenden neuer SQL Server 2016-Möglichkeiten:

CREATE FUNCTION ToLocalTime(@dtUtc datetime, @timezoneId nvarchar(256))
RETURNS datetime
AS BEGIN

return @dtUtc AT TIME ZONE 'UTC' AT TIME ZONE @timezoneId

/* -- second way, faster

return SWITCHOFFSET(@dtUtc , DATENAME(tz, @dtUtc AT TIME ZONE @timezoneId))

*/

/* -- third way

declare @dtLocal datetimeoffset
set @dtLocal = @dtUtc AT TIME ZONE @timezoneId
return dateadd(minute, DATEPART (TZoffset, @dtLocal), @dtUtc)

*/

END
GO

Aber das Clr-Verfahren arbeitet fünfmal schneller: '- (

Beachten Sie, dass der Offset für eine Zeitzone in Winter- oder Sommerzeit geändert werden kann. Zum Beispiel

select cast('2017-02-08 09:00:00.000' as datetime) AT TIME ZONE 'Eastern Standard Time'
select cast('2017-08-08 09:00:00.000' as datetime) AT TIME ZONE 'Eastern Standard Time'

ergebnisse:

2017-02-08 09:00:00.000 -05:00
2017-08-08 09:00:00.000 -04:00

Sie können nicht einfach einen konstanten Versatz hinzufügen.

6

Wenn die Aktivierung der CLR für Ihre Datenbank sowie die Verwendung der Zeitzone des SQL-Servers eine Option ist, kann sie ganz einfach in .NET geschrieben werden.

public partial class UserDefinedFunctions
{
    [Microsoft.SqlServer.Server.SqlFunction]
    public static SqlDateTime fn_GetLocalFromUTC(SqlDateTime UTC)
    {
        if (UTC.IsNull)
            return UTC;

        return new SqlDateTime(UTC.Value.ToLocalTime());
    }
}

Ein UTC-Datumszeitwert geht ein und der lokale Datumszeitwert relativ zum Server wird ausgegeben. Nullwerte geben Null zurück.

5
JGates

Hier ist eine Version, die Sommerzeit und UTC-Offset berücksichtigt und nicht an ein bestimmtes Jahr gebunden ist.

---------------------------------------------------------------------------------------------------
--Name:     udfToLocalTime.sql
--Purpose:  To convert UTC to local US time accounting for DST
--Author:   Patrick Slesicki
--Date:     3/25/2014
--Notes:    Works on SQL Server 2008R2 and later, maybe SQL Server 2008 as well.
--          Good only for US States observing the Energy Policy Act of 2005.
--          Function doesn't apply for years prior to 2007.
--          Function assumes that the 1st day of the week is Sunday.
--Tests:        
--          SELECT dbo.udfToLocalTime('2014-03-09 9:00', DEFAULT)
--          SELECT dbo.udfToLocalTime('2014-03-09 10:00', DEFAULT)
--          SELECT dbo.udfToLocalTime('2014-11-02 8:00', DEFAULT)
--          SELECT dbo.udfToLocalTime('2014-11-02 9:00', DEFAULT)
---------------------------------------------------------------------------------------------------
ALTER FUNCTION udfToLocalTime
    (
    @UtcDateTime    AS DATETIME
    ,@UtcOffset     AS INT = -8 --PST
    )
RETURNS DATETIME
AS 
BEGIN
    DECLARE 
        @PstDateTime    AS DATETIME
        ,@Year          AS CHAR(4)
        ,@DstStart      AS DATETIME
        ,@DstEnd        AS DATETIME
        ,@Mar1          AS DATETIME
        ,@Nov1          AS DATETIME
        ,@MarTime       AS TIME
        ,@NovTime       AS TIME
        ,@Mar1Day       AS INT
        ,@Nov1Day       AS INT
        ,@MarDiff       AS INT
        ,@NovDiff       AS INT

    SELECT
        @Year       = YEAR(@UtcDateTime)
        ,@MarTime   = CONVERT(TIME, DATEADD(HOUR, [email protected], '1900-01-01 02:00'))
        ,@NovTime   = CONVERT(TIME, DATEADD(HOUR, [email protected] - 1, '1900-01-01 02:00'))
        ,@Mar1      = CONVERT(CHAR(16), @Year + '-03-01 ' + CONVERT(CHAR(5), @MarTime), 126)
        ,@Nov1      = CONVERT(CHAR(16), @Year + '-11-01 ' + CONVERT(CHAR(5), @NovTime), 126)
        ,@Mar1Day   = DATEPART(WEEKDAY, @Mar1)
        ,@Nov1Day   = DATEPART(WEEKDAY, @Nov1)

    --Get number of days between Mar 1 and DST start date
    IF @Mar1Day = 1 SET @MarDiff = 7
    ELSE SET @MarDiff = 15 - @Mar1Day

    --Get number of days between Nov 1 and DST end date
    IF @Nov1Day = 1 SET @NovDiff = 0
    ELSE SET @NovDiff = 8 - @Nov1Day

    --Get DST start and end dates
    SELECT 
        @DstStart   = DATEADD(DAY, @MarDiff, @Mar1)
        ,@DstEnd    = DATEADD(DAY, @NovDiff, @Nov1)

    --Change UTC offset if @UtcDateTime is in DST Range
    IF @UtcDateTime >= @DstStart AND @UtcDateTime < @DstEnd SET @UtcOffset = @UtcOffset + 1

    --Get Conversion
    SET @PstDateTime = DATEADD(HOUR, @UtcOffset, @UtcDateTime)
    RETURN @PstDateTime
END
GO
4

Es gibt keinen einfachen Weg, dies auf korrekte und generische Weise zu tun.

Zunächst ist zu verstehen, dass der Versatz von dem betreffenden Datum, der Zeitzone UND dem DST abhängt. GetDate()-GetUTCDate gibt Ihnen nur den heutigen Versatz in der TZ des Servers an, der nicht relevant ist.

Ich habe nur zwei funktionierende Lösungen gesehen und ich habe viel gesucht.

1) Eine benutzerdefinierte SQL-Funktion mit ein paar Tabellen mit Basisdaten wie Zeitzonen und DST-Regeln pro TZ . Funktioniert aber nicht sehr elegant. Ich kann es nicht posten, da mir der Code nicht gehört.

BEARBEITEN: Hier ist ein Beispiel für diese Methode https://Gist.github.com/drumsta/16b79cee6bc195cd89c8

2) Fügen Sie der DB eine .net-Assembly hinzu. .Net kann dies sehr einfach durchführen. Dies funktioniert sehr gut, aber der Nachteil ist, dass Sie mehrere Parameter auf Serverebene konfigurieren müssen und die Konfiguration leicht abgebrochen werden kann, z. Wenn Sie die Datenbank wiederherstellen ... Ich verwende diese Methode, kann sie jedoch nicht posten, da mir der Code nicht gehört. 

4
vikjon0

Ich fand die einmalige Funktion zu langsam, wenn viele Daten vorhanden sind. Also tat ich es, indem ich mich einer Tabellenfunktion anschloss, die eine Berechnung des Stundenunterschieds erlaubte. Im Grunde handelt es sich um Zeitsegmente mit dem Stundenversatz. Ein Jahr wäre 4 Reihen. Also die Tischfunktion

dbo.fn_getTimeZoneOffsets('3/1/2007 7:00am', '11/5/2007 9:00am', 'EPT')

würde diese Tabelle zurückgeben:

startTime          endTime   offset  isHr2
3/1/07 7:00     3/11/07 6:59    -5    0
3/11/07 7:00    11/4/07 6:59    -4    0
11/4/07 7:00    11/4/07 7:59    -5    1
11/4/07 8:00    11/5/07 9:00    -5    0

Es berücksichtigt die Sommerzeit. Ein Beispiel, wie es verwendet wird, ist unten und der vollständige Blogpost ist hier .

select mt.startTime as startUTC, 
    dateadd(hh, tzStart.offset, mt.startTime) as startLocal, 
    tzStart.isHr2
from MyTable mt 
inner join dbo.fn_getTimeZoneOffsets(@startViewUTC, @endViewUTC, @timeZone)  tzStart
on mt.startTime between tzStart.startTime and tzStart.endTime
3
JBrooks
 declare @mydate2 datetime
 set @mydate2=Getdate()
 select @mydate2 as mydate,
 dateadd(minute, datediff(minute,getdate(),@mydate2),getutcdate())
2

Keines davon funktionierte für mich, aber unten funktionierte es zu 100%. Ich hoffe, dass dies anderen helfen kann, die versuchen, es so umzusetzen, wie ich es war.

CREATE FUNCTION [dbo].[fn_UTC_to_EST]
(
    @UTC datetime,
    @StandardOffset int
)
RETURNS datetime
AS
BEGIN

declare 
    @DST datetime,
    @SSM datetime, -- Second Sunday in March
    @FSN datetime  -- First Sunday in November
-- get DST Range
set @SSM = DATEADD(dd,7 + (6-(DATEDIFF(dd,0,DATEADD(mm,(YEAR(GETDATE())-1900) * 12 + 2,0))%7)),DATEADD(mm,(YEAR(GETDATE())-1900) * 12 + 2,0))+'02:00:00' 
set @FSN = DATEADD(dd, (6-(DATEDIFF(dd,0,DATEADD(mm,(YEAR(GETDATE())-1900) * 12 + 10,0))%7)),DATEADD(mm,(YEAR(GETDATE())-1900) * 12 + 10,0)) +'02:00:00'

-- add an hour to @StandardOffset if @UTC is in DST range
if @UTC between @SSM and @FSN
    set @StandardOffset = @StandardOffset + 1

-- convert to DST
set @DST = dateadd(hour,@StandardOffset,@UTC)

-- return converted datetime
return @DST

END
2
Mike

Der UNIX-Zeitstempel ist lediglich die Anzahl von Sekunden zwischen einem bestimmten Datum und der Unix-Epoche. 

SELECT DATEDIFF (SECOND, {d '1970-01-01'}, GETDATE ()) // Dies gibt den UNIX-Zeitstempel im SQL-Server zurück

sie können eine Funktion für die lokale Datumszeit in Unix-UTC-Konvertierung erstellen, indem Sie Country Offset Funktion in Unix-Zeitstempel im SQL-Server verwenden

1
Vasanthlal V A

Für Benutzer von Azure SQL und @@Version> = SQL Server 2016 ist im Folgenden eine einfache Funktion mit AT TIME ZONE aufgeführt.

CREATE FUNCTION [dbo].[Global_Convert_UTCTimeTo_LocalTime]
(
   @LocalTimeZone        VARCHAR(50),
   @UTCDateTime          DATETIME
)
RETURNS DATETIME
AS
BEGIN
   DECLARE @ConvertedDateTime DATETIME;

   SELECT @ConvertedDateTime = @UTCDateTime AT TIME ZONE 'UTC' AT TIME ZONE @LocalTimeZone
   RETURN @ConvertedDateTime

END
GO

Informationen zu den Arten von Werten, die @LocalTimeZone annehmen kann, finden Sie unter link oder unter KEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones.

1
Ranger

Dies kann ohne Funktion erfolgen. Mit dem folgenden Code wird eine UTC-Zeit in eine Bergzeit umgerechnet, die Sommerzeit berücksichtigt. Passen Sie alle -6- und -7-Zahlen entsprechend an Ihre Zeitzone an (d. H. Für EST würden Sie auf -4 bzw. -5 einstellen)

--Adjust a UTC value, in the example the UTC field is identified as UTC.Field, to account for daylight savings time when converting out of UTC to Mountain time.
CASE
    --When it's between March and November, it is summer time which is -6 from UTC
    WHEN MONTH ( UTC.Field ) > 3 AND MONTH ( UTC.Field ) < 11 
        THEN DATEADD ( HOUR , -6 , UTC.Field )
    --When its March and the day is greater than the 14, you know it's summer (-6)
    WHEN MONTH ( UTC.Field ) = 3
        AND DATEPART ( DAY , UTC.Field ) >= 14 
        THEN
            --However, if UTC is before 9am on that Sunday, then it's before 2am Mountain which means it's still Winter daylight time.
            CASE 
                WHEN DATEPART ( WEEKDAY , UTC.Field ) = 1 
                    AND UTC.Field < '9:00'
                    --Before 2am mountain time so it's winter, -7 hours for Winter daylight time
                    THEN DATEADD ( HOUR , -7 , UTC.Field )
                --Otherwise -6 because it'll be after 2am making it Summer daylight time
                ELSE DATEADD ( HOUR , -6 , UTC.Field )
            END
    WHEN MONTH ( UTC.Field ) = 3
        AND ( DATEPART ( WEEKDAY , UTC.Field ) + 7 ) <= DATEPART ( day , UTC.Field ) 
        THEN 
            --According to the date, it's moved onto Summer daylight, but we need to account for the hours leading up to 2am if it's Sunday
            CASE 
                WHEN DATEPART ( WEEKDAY , UTC.Field ) = 1 
                    AND UTC.Field < '9:00'
                    --Before 9am UTC is before 2am Mountain so it's winter Daylight, -7 hours
                    THEN DATEADD ( HOUR , -7 , UTC.Field )
                --Otherwise, it's summer daylight, -6 hours
                ELSE DATEADD ( HOUR , -6 , UTC.Field )
            END
    --When it's November and the weekday is greater than the calendar date, it's still Summer so -6 from the time
    WHEN MONTH ( UTC.Field ) = 11
        AND DATEPART ( WEEKDAY , UTC.Field ) > DATEPART ( DAY , UTC.Field ) 
        THEN DATEADD ( HOUR , -6 , UTC.Field )
    WHEN MONTH ( UTC.Field ) = 11
        AND DATEPART ( WEEKDAY , UTC.Field ) <= DATEPART ( DAY , UTC.Field ) 
            --If the weekday is less than or equal to the calendar day it's Winter daylight but we need to account for the hours leading up to 2am.
            CASE 
                WHEN DATEPART ( WEEKDAY , UTC.Field ) = 1 
                    AND UTC.Field < '8:00'
                    --If it's before 8am UTC and it's Sunday in the logic outlined, then it's still Summer daylight, -6 hours
                    THEN DATEADD ( HOUR , -6 , UTC.Field )
                --Otherwise, adjust for Winter daylight at -7
                ELSE DATEADD ( HOUR , -7 , UTC.Field )
            END
    --If the date doesn't fall into any of the above logic, it's Winter daylight, -7
    ELSE
        DATEADD ( HOUR , -7 , UTC.Field )
END
1
Alex Fenech

Rons Antwort enthält einen Fehler. Es wird die Ortszeit um 2:00 Uhr verwendet, in der UTC-Äquivalent erforderlich ist. Ich habe nicht genügend Reputationspunkte, um Rons Antwort zu kommentieren. Eine korrigierte Version wird unten angezeigt:

-- =============================================
-- Author:      Ron Smith
-- Create date: 2013-10-23
-- Description: Converts UTC to DST
--              based on passed Standard offset
-- =============================================
CREATE FUNCTION [dbo].[fn_UTC_to_DST]
(
    @UTC datetime,
    @StandardOffset int
)
RETURNS datetime
AS
BEGIN

declare 
    @DST datetime,
    @SSM datetime, -- Second Sunday in March
    @FSN datetime  -- First Sunday in November
-- get DST Range
set @SSM = datename(year,@UTC) + '0314' 
set @SSM = dateadd(hour,2 - @StandardOffset,dateadd(day,datepart(dw,@SSM)*-1+1,@SSM))
set @FSN = datename(year,@UTC) + '1107'
set @FSN = dateadd(second,-1,dateadd(hour,2 - (@StandardOffset + 1),dateadd(day,datepart(dw,@FSN)*-1+1,@FSN)))

-- add an hour to @StandardOffset if @UTC is in DST range
if @UTC between @SSM and @FSN
    set @StandardOffset = @StandardOffset + 1

-- convert to DST
set @DST = dateadd(hour,@StandardOffset,@UTC)

-- return converted datetime
return @DST

END
1
jlspublic

Es ist einfach. Versuchen Sie Folgendes für Azure SQL Server:

SELECT YourDateTimeColumn AT TIME ZONE 'Eastern Standard Time' FROM YourTable

Für lokalen SQL Server:

SELECT CONVERT (datetime2, SWITCHOFFSET (CONVERT (datetimeoffset, gETDATE ()), DATENAME (TzOffset, gETDATE () AT ZEITZONE 'Eastern Standard Time'))) von YourTable

0
lijuthomas

Sie müssen den String neu formatieren und zur richtigen Zeit konvertieren. In diesem Fall brauchte ich Zulu-Zeit.

Declare @Date datetime;
Declare @DateString varchar(50);
set @Date = GETDATE(); 
declare @ZuluTime datetime;

Declare @DateFrom varchar (50);
Declare @DateTo varchar (50);
set @ZuluTime = DATEADD(second, DATEDIFF(second, GETDATE(), GETUTCDATE()), @Date);
set @DateString =  FORMAT(@ZuluTime, 'yyyy-MM-ddThh:mm:ssZ', 'en-US' )  
select @DateString;
0
Tommyz

Für Azure und SQL Server 2016 und höher können Sie Folgendes ausführen:

select YourDateTimeUtcColumn AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time' as LocalTime from YourTable

Die vollständige Liste der Zeitzonen-Namen finden Sie in diesem Beitrag: Liste der Zeitzonen-IDs zur Verwendung mit FindTimeZoneById () in C #?

Und ja, die Zeitzonen sind falsch benannt - obwohl es "Eastern Standard Time" ist, wird die Sommerzeit berücksichtigt.

0
Matt Frear

Bester Weg für Oracle:

Mit fest codierten Datum/Uhrzeit:

SELECT TO_CHAR(CAST((FROM_TZ(CAST(TO_DATE('2018-10-27 21:00', 'YYYY-MM-DD HH24:MI') AS TIMESTAMP), 'UTC') AT  TIME ZONE 'EET') AS DATE), 'YYYY-MM-DD HH24:MI') UTC_TO_EET FROM DUAL

Result:2018-10-28 00:00

Mit Spalten- und Tabellennamen:

SELECT TO_CHAR(CAST((FROM_TZ(CAST(COLUMN_NAME AS TIMESTAMP), 'UTC') AT  TIME ZONE 'EET') AS DATE), 'YYYY-MM-DD HH24:MI') UTC_TO_EET FROM TABLE_NAME
0
BOB

Erste Funktion: konfiguriert für italienische Zeitzone (+1, +2), Datumswechsel: letzter Sonntag im März und Oktober, geben Sie die Differenz zwischen der aktuellen Zeitzone und der Datumszeit als Parameter zurück. 

Returns:
current timezone < parameter timezone ==> +1
current timezone > parameter timezone ==> -1
else 0

Der Code lautet:

CREATE FUNCTION [dbo].[UF_ADJUST_OFFSET]
(
    @dt_utc datetime2(7)
)
RETURNS INT
AS
BEGIN


declare @month int,
        @year int,
        @current_offset int,
        @offset_since int,
        @offset int,
        @yearmonth varchar(8),
        @changeoffsetdate datetime2(7)

declare @lastweek table(giorno datetime2(7))

select @current_offset = DATEDIFF(hh, GETUTCDATE(), GETDATE())

select @month = datepart(month, @dt_utc)

if @month < 3 or @month > 10 Begin Set @offset_since = 1 Goto JMP End

if @month > 3 and @month < 10 Begin Set @offset_since = 2 Goto JMP End

--If i'm here is march or october
select @year = datepart(yyyy, @dt_utc)

if @month = 3
Begin

Set @yearmonth = cast(@year as varchar) + '-03-'

Insert Into @lastweek Values(@yearmonth + '31 03:00:00.000000'),(@yearmonth + '30 03:00:00.000000'),(@yearmonth + '29 03:00:00.000000'),(@yearmonth + '28 03:00:00.000000'),
                         (@yearmonth + '27 03:00:00.000000'),(@yearmonth + '26 03:00:00.000000'),(@yearmonth + '25 03:00:00.000000')

--Last week of march
Select @changeoffsetdate = giorno From @lastweek Where  datepart(weekday, giorno) = 1

    if @dt_utc < @changeoffsetdate 
    Begin 
        Set @offset_since = 1 
    End Else Begin
        Set @offset_since = 2
    End
End

if @month = 10
Begin

Set @yearmonth = cast(@year as varchar) + '-10-'

Insert Into @lastweek Values(@yearmonth + '31 03:00:00.000000'),(@yearmonth + '30 03:00:00.000000'),(@yearmonth + '29 03:00:00.000000'),(@yearmonth + '28 03:00:00.000000'),
                         (@yearmonth + '27 03:00:00.000000'),(@yearmonth + '26 03:00:00.000000'),(@yearmonth + '25 03:00:00.000000')

--Last week of october
Select @changeoffsetdate = giorno From @lastweek Where  datepart(weekday, giorno) = 1

    if @dt_utc > @changeoffsetdate 
    Begin 
        Set @offset_since = 1 
    End Else Begin
        Set @offset_since = 2
    End
End

JMP:

if @current_offset < @offset_since Begin
    Set @offset = 1
End Else if @current_offset > @offset_since Set @offset = -1 Else Set @offset = 0

Return @offset

END

Dann die Funktion, die das Datum konvertiert

CREATE FUNCTION [dbo].[UF_CONVERT]
(
    @dt_utc datetime2(7)
)
RETURNS datetime
AS
BEGIN

    declare @offset int


    Select @offset = dbo.UF_ADJUST_OFFSET(@dt_utc)

    if @dt_utc >= '9999-12-31 22:59:59.9999999'
        set @dt_utc = '9999-12-31 23:59:59.9999999'
    Else
        set @dt_utc = (SELECT DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), @dt_utc) )

    if @offset <> 0
        Set @dt_utc = dateadd(hh, @offset, @dt_utc)

    RETURN @dt_utc

END
0
GigiS

Ich habe Code, um UTC zu lokalen und lokalen zu UTC-Zeiten durchzuführen, die die Konvertierung mit Code wie diesem ermöglichen

DECLARE @usersTimezone VARCHAR(32)='Europe/London'
DECLARE @utcDT DATETIME=GetUTCDate()
DECLARE @userDT DATETIME=[dbo].[funcUTCtoLocal](@utcDT, @usersTimezone)

und

DECLARE @usersTimezone VARCHAR(32)='Europe/London'
DECLARE @userDT DATETIME=GetDate()
DECLARE @utcDT DATETIME=[dbo].[funcLocaltoUTC](@userDT, @usersTimezone)

Die Funktionen können alle oder einen Teil der von NodaTime bereitgestellten Zeitzonen in der IANA/TZDB unterstützen - siehe vollständige Liste unter https://nodatime.org/TimeZones

Beachten Sie, dass mein Anwendungsfall bedeutet, dass ich nur ein "aktuelles" Fenster benötige, das die Umrechnung von Zeiten in einem Bereich von ca. +/- 5 Jahren ermöglicht. Dies bedeutet, dass die von mir verwendete Methode wahrscheinlich nicht für Sie geeignet ist, wenn Sie einen sehr langen Zeitraum benötigen, da sie Code für jedes Zeitzonenintervall in einem bestimmten Datumsbereich generiert.

Das Projekt ist auf GitHub: https://github.com/elliveny/SQLServerTimeConversion

Dadurch wird der SQL-Funktionscode gemäß in diesem Beispiel generiert

0
Elliveny

Dies sollte in der Lage sein, Serverzeit mit DST zu erhalten

declare @dt datetime
set @dt = getutcdate() -- GMT equivalent

sysdatetimeoffset berücksichtigt DST

select [InputTime] = @dt
       , [LocalTime2] = dateadd(mi, datediff(mi, sysdatetimeoffset(),getdate()), @dt) 
0
DiAm

Als Warnung - wenn Sie Folgendes verwenden (beachten Sie die Millisekunden statt der Minuten):

    SELECT DATEADD(ms, DATEDIFF(ms, GETUTCDATE(), GETDATE()), MyTable.UtcColumn) 
    AS ColumnInLocalTime
    FROM MyTable

Beachten Sie, dass der DATEDIFF-Teil nicht immer dieselbe Nummer zurückgibt. Verwenden Sie es daher nicht, um DateTimes bis auf Millisekunden zu vergleichen.

0
Sasquatch

- Holen Sie sich indische Normalzeit von utc

CREATE FUNCTION dbo.getISTTime
(
@UTCDate datetime
)
RETURNS datetime
AS
BEGIN

    RETURN dateadd(minute,330,@UTCDate)

END
GO
0
Meghraj Swami

Ich habe festgestellt, dass diese Funktion schneller ist als andere Lösungen, die eine separate Tabelle oder Schleifen verwenden. Es ist nur eine grundlegende Aussage. Da alle Monate zwischen April und Oktober einen Zeitunterschied von -4 Stunden (östliche Zeit) aufweisen, müssen wir nur noch ein paar Fallzeilen für die Nebentage hinzufügen. Ansonsten beträgt der Versatz -5 Stunden.

Dies ist spezifisch für eine Konvertierung von UTC in östliche Zeit, jedoch können bei Bedarf zusätzliche Zeitzonenfunktionen hinzugefügt werden.

USE [YourDatabaseName]
GO

/****** Object:  UserDefinedFunction [dbo].[ConvertUTCtoEastern]    Script Date: 11/2/2016 5:21:52 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


CREATE FUNCTION [dbo].[ConvertUTCtoEastern]
(
@dtStartDate DATETIME
)
RETURNS DATETIME
AS
BEGIN
DECLARE @Working DATETIME
DECLARE @Returned DATETIME

SET @Working = @dtStartDate
SET @Working = 
case when month(@Working) between 4 and 10 then dateadd(HH,-4,@Working) 
     when @Working between '2017-03-12' and '2017-11-05' then dateadd(HH,-4,@Working) 
     when @Working between '2016-03-13' and '2016-11-06' then dateadd(HH,-4,@Working) 
     when @Working between '2015-03-08' and '2015-11-01' then dateadd(HH,-4,@Working) 
     when @Working between '2014-03-09' and '2014-11-02' then dateadd(HH,-4,@Working) 
     when @Working between '2013-03-10' and '2013-11-03' then dateadd(HH,-4,@Working) 
     when @Working between '2012-03-11' and '2012-11-04' then dateadd(HH,-4,@Working) 
else dateadd(HH,-5,@Working) end

SET @Returned = @Working

RETURN @Returned

END


GO
0
Jason Green