चयनित समय कथन में UTC से स्थानीय समय में डेटाटाइम कॉलम में कनवर्ट करें


208

मैं कुछ SQL चयन क्वेरी कर रहा हूँ और अपने क्वेरी परिणामों में स्थानीय समय के रूप में प्रदर्शित होने के लिए अपने UTC डेटाटाइम कॉलम को स्थानीय समय में परिवर्तित करना चाहूंगा। ध्यान दें, मैं इस रूपांतरण को कोड के माध्यम से करना नहीं चाह रहा हूं, बल्कि जब मैं अपने डेटाबेस के खिलाफ मैनुअल और यादृच्छिक SQL प्रश्न कर रहा हूं।


क्या यह सवाल आपकी परिस्थितियों के समान है? stackoverflow.com/questions/3404646/…
Taryn East

जवाबों:


322

आप इसे SQL Server 2008 या इससे अधिक पर निम्नानुसार कर सकते हैं:

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

आप निम्न क्रिया भी कर सकते हैं:

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

आप जो कुछ भी करते हैं, तारीखों को घटाने के लिए उपयोग नहीं करते हैं -, क्योंकि ऑपरेशन परमाणु नहीं है, और आप अवसर पर सिस्टम डेटाइम और स्थानीय डेटाटाइम के बीच अलग-अलग समय पर जाँच की जा रही परिस्थितियों के कारण अनिश्चित परिणाम प्राप्त कर सकते हैं (यानी, गैर-व्यावहारिक रूप से) ।

कृपया ध्यान दें कि यह उत्तर डीएसटी को ध्यान में नहीं रखता है। यदि आप DST समायोजन शामिल करना चाहते हैं, तो कृपया निम्न SO प्रश्न भी देखें:

SQL सर्वर में डेलाइट सेविंग टाइम स्टार्ट एंड एंड फंक्शन कैसे बनाएं


38
क्या दिन प्रकाश बचत के लिए इस खाते को बनाने का कोई तरीका है?
स्टीव

15
मुझे यहां टाइम ज़ोन का नाम नहीं दिखता है इसलिए यह गलत है। यह मान लेना बहुत बुरा विचार है कि आप अंकगणित करके स्थानीय समय में परिवर्तित हो सकते हैं
जॉनी रास

7
@MichaelGoldshteyn यदि आपके पास एक समयक्षेत्र ऑफसेट है तो आपको अभी भी पता नहीं है कि एक समय तार्किक समय क्या है? Timezones सामाजिक चीजें हैं और विभिन्न बिंदुओं पर सरकारों द्वारा इसे बदला जा सकता है। समय / इतिहास में विभिन्न बिंदुओं पर एक समयक्षेत्र के लिए ऑफसेट अलग-अलग हो सकता है (गर्मियों का समय एक सामान्य होने के नाते)। आप UTC से वर्तमान ऑफ़सेट द्वारा समय की भरपाई कर रहे हैं ... एक और बात यह है कि इससे सर्वर का टाइमज़ोन मिलेगा और क्लाइंट को नहीं, जो एक अलग देश में होस्ट करने पर आगे की समस्या हो सकती है।
जॉनीराया

4
@ निलोफर सरल उत्तर यह है कि आपको नहीं करना चाहिए, और नहीं करना चाहिए। डेटासेट हमेशा UTC में संग्रहीत किया जाना चाहिए (अधिमानतः डेटाबेस सर्वर की घड़ी के आधार पर, वेबसर्वर का नहीं, एप्लिकेशन सर्वर का, और निश्चित रूप से क्लाइंट की घड़ी का नहीं)। यह प्रदर्शित करना कि डेटाइम UI परत के लिए एक फ़ंक्शन है, और यह डेटाटाइम को आपके इच्छित प्रारूप में परिवर्तित करने के लिए ज़िम्मेदार है (यदि आवश्यक हो तो एक टाइमज़ोन सहित)।
रॉबर्ट मैककी

11
Sql azure का उपयोग करने वाले किसी भी व्यक्ति के लिए यह दृष्टिकोण काम नहीं करेगा क्योंकि दिनांक / समय फ़ंक्शन सभी UTC को वापस करते हैं, इसलिए GETDATE () से GETUTCDATE () की तुलना करने से आपको काम करने के लिए कुछ भी नहीं मिलता है और आपका परिणाम वैसा ही होता है जैसा आपने शुरू किया था।
ब्रायन सुरोइक

59

मुझे इनमें से कोई भी उदाहरण यूटीसी के रूप में संग्रहित करने में मदद करने के लिए एक निर्दिष्ट टाइमज़ोन में डेटाइम के रूप में संग्रहीत नहीं किया गया है (सर्वर का समय क्षेत्र नहीं है क्योंकि एज़्योर SQL डेटाबेस यूटीसी के रूप में चलते हैं)। इस तरह मैंने इसे संभाला। यह सुरुचिपूर्ण नहीं है, लेकिन यह सरल है और अन्य तालिकाओं को बनाए बिना आपको सही उत्तर देता है:

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

4
केवल 2016 के लिए काम करता है और सिस्टम रजिस्ट्री का उपयोग करता है। लेकिन एज़्योर के लिए महान समाधान।
डेन क्यूंडी

2
यह एक UTC में संग्रहीत बार के लिए काम करता है, धन्यवाद दोस्तों
Null

3
यहाँ आप समय क्षेत्र के लिए उपयोग किए जा सकने वाले तार की एक सूची दे सकते हैं: stackoverflow.com/a/7908482/631277
मैट केम्प

1
यदि SQL 2016 और AT TIME ZONEसिंटैक्स का उपयोग कर रहे हैं , तो stackoverflow.com/a/44941536/112764 पर विचार करें - आप एक साथ कई एस को जोड़कर कई रूपांतरणों की श्रृंखला बना सकते हैं at time zone <blah>
नैटज

3
यह थोड़ा अजीब है, भी, लेकिन कुछ बहुत ही बुनियादी परीक्षण ऐसा लग रहा है कि यह भी काम कर सकता है, dateTimeField AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time'- सिर्फ AT TIME ZONEबयानों का पीछा करते हुए। (@NateJ ने ऊपर यह उल्लेख किया है जो मैं अभी देख रहा हूं)
डेविड मोहुंड्रो

22

यदि आपकी स्थानीय तिथि समय कहा गया है Eastern Standard Timeऔर आप UTC से उस में बदलना चाहते हैं, तो Azure SQL और SQL Server 2016 और इसके बाद के संस्करण में, आप यह कर सकते हैं:

SELECT YourUtcColumn AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time' AS
       LocalTime
FROM   YourTable

समयक्षेत्र के नामों की पूरी सूची निम्न के साथ मिल सकती है:

SELECT * FROM sys.time_zone_info 

और हाँ, टाइमज़ोन बुरी तरह से नामित हैं - भले ही यह है Eastern Standard Time, दिन के उजाले की बचत को ध्यान में रखा जाता है।


2
Timezones और offsets यहां SQL सर्वर में भी पाए जा सकते हैं: SELECT * FROM sys.time_zone_info
rayzinnz

21

यदि आपको अपने सर्वर के स्थान के अलावा रूपांतरण की आवश्यकता है, तो यहां एक फ़ंक्शन है जो आपको एक मानक ऑफसेट और यूएस डेलाइट सेविंग टाइम्स के लिए खातों को पारित करने की अनुमति देता है:

-- =============================================
-- 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

2
रॉन स्मिथ मुझे पता है कि यह एक पुरानी पोस्ट है लेकिन मैं उत्सुक था कि हार्ड कोडेड '0314' और '1107' डीएसटी रेंज की प्राप्ति में क्या दर्शाते हैं। यह कठोर कोडित दिन प्रतीत होता है जो DTS के कारण बदलते हैं। जब आप गणना की गई तारीख होनी चाहिए, तो आप इसे क्यों कोड करेंगे क्योंकि मार्च के दूसरे रविवार को कैलेंडर के आधार पर दिन बदल जाते हैं और नवंबर का पहला रविवार पड़ता है। कठिन कोडित दिन इस कोड को मौलिक रूप से त्रुटिपूर्ण बना देंगे।
माइक

2
अच्छा सवाल :) वे अधिकतम तारीखें हैं जहां मार्च में दूसरा रविवार और नवंबर में पहला रविवार हो सकता है। निम्न पंक्तियाँ चर को वास्तविक दिनांक पर सेट करती हैं।
रॉन स्मिथ

8

नए SQL सर्वर 2016 के अवसरों का उपयोग करना:

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

लेकिन clr प्रक्रिया 5 गुना तेजी से काम करती है: '- (

ध्यान दें कि एक TimeZone के लिए ऑफसेट सर्दी या गर्मी के समय में बदल सकता है। उदाहरण के लिए

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'

परिणाम:

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

आप बस निरंतर ऑफसेट नहीं जोड़ सकते।


5

यदि आपके डेटाबेस पर सीएलआर को सक्षम करना एक विकल्प है और साथ ही एसक्यूएल सर्वर के टाइमज़ोन का उपयोग करना है, तो इसे बहुत आसानी से लिखा जा सकता है।

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());
    }
}

एक UTC डेटाटाइम मान अंदर जाता है और सर्वर के सापेक्ष स्थानीय डेटटाइम मान बाहर आता है। अशक्त मान लौट आते हैं।


5

इसे सही और सामान्य तरीके से करने का कोई सरल तरीका नहीं है।

सबसे पहले यह समझना चाहिए कि ऑफसेट प्रश्न, समय क्षेत्र और डीएसटी की तारीख में निर्भर करता है। GetDate()-GetUTCDateकेवल आपको सर्वर के टीबी पर ऑफसेट देता है, जो प्रासंगिक नहीं है।

मैंने केवल दो कामकाजी समाधान देखे हैं और मैंने बहुत कुछ खोजा है।

1) आधार डेटा की एक जोड़ी के साथ एक कस्टम SQL फ़ंक्शन, जैसे कि समय क्षेत्र और DST प्रति TZ नियम। काम कर रहे हैं लेकिन बहुत सुरुचिपूर्ण नहीं हैं। मैं इसे पोस्ट नहीं कर सकता क्योंकि मेरे पास कोड नहीं है।

EDIT: यहाँ इस विधि का एक उदाहरण है https://gist.github.com/drumsta/16b79cee6bc195cd89c8

2) d .net असेंबली में .net असेंबली जोड़ें, यह बहुत आसानी से कर सकता है। यह बहुत अच्छी तरह से काम कर रहा है, लेकिन नकारात्मक पक्ष यह है कि आपको सर्वर के स्तर पर कई मापदंडों को कॉन्फ़िगर करने की आवश्यकता है और डेटाबेस को पुनर्स्थापित करने पर कॉन्फ़िगरेशन आसानी से टूट जाता है जैसे। मैं इस पद्धति का उपयोग करता हूं, लेकिन मैं इसे पोस्ट नहीं कर सकता क्योंकि मेरे पास कोड नहीं है।


4

इनमें से किसी ने भी मेरे लिए काम नहीं किया लेकिन इसने 100% काम किया। आशा है कि यह दूसरों को इसे बदलने में मदद कर सकता है जैसे मैं था।

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

1
यह स्वीकृत उत्तर होना चाहिए। केवल एक चीज जो मैं बदलूंगा वह नाम है क्योंकि इसका अर्थ है कि यह ईएसटी समय के लिए है, जब वास्तव में यह स्थानीय समय के लिए है और स्टैंडर्डऑफसेट को एक पैरामीटर के रूप में पारित किया जाता है।
ग्रेग गम

सहमत, सबसे अच्छा जवाब ... लेकिन एक पैरामीटर के रूप में ऑफसेट में पास होने के बजाय, मैंने इसे फ़ंक्शन बॉडी के भीतर जोड़ा:declare @StandardOffset int = datediff (hh, GETUTCDATE(), GETDATE())
टॉम वॉरफील्ड

मेरे पिछले सुगर के बाद - यदि आप @StandardOffset की गणना करते हैं, तो आपको DST सुधार करने की आवश्यकता नहीं है।
टॉम वॉरफील्ड

3

यहां एक संस्करण है जो दिन की बचत, यूटीसी ऑफसेट के लिए जिम्मेदार है, और एक विशेष वर्ष में बंद नहीं है।

---------------------------------------------------------------------------------------------------
--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, -@UtcOffset, '1900-01-01 02:00'))
        ,@NovTime   = CONVERT(TIME, DATEADD(HOUR, -@UtcOffset - 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

3

मैंने पाया कि बहुत अधिक डेटा होने पर फ़ंक्शन बंद होने का तरीका बहुत धीमा है। इसलिए मैंने इसे एक टेबल फंक्शन में शामिल होने के माध्यम से किया जो कि घंटे के अंतर की गणना के लिए अनुमति देगा। यह मूल रूप से घंटे की भरपाई के साथ डेटाटाइम सेगमेंट है। एक वर्ष में 4 पंक्तियाँ होंगी। तो टेबल फ़ंक्शन

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

इस तालिका को वापस करेगा:

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

यह दिन के उजाले की बचत के लिए खाता है। इसका उपयोग कैसे किया जाता है इसका एक नमूना नीचे है और पूर्ण ब्लॉग पोस्ट यहाँ है

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

यह डीएसटी पर सही तरीके से विचार नहीं करता है। यकीन नहीं होता अगर आप मान लें कि केवल यूएस ही मौजूद है और डीएसटी के नियम कभी नहीं बदलते हैं।
vikjon0

@ vikjon0 हां, जिस प्रोजेक्ट के लिए मैंने इसे बनाया था उसमें केवल यूएस टाइम जोन थे।
JBrooks

2
 declare @mydate2 datetime
 set @mydate2=Getdate()
 select @mydate2 as mydate,
 dateadd(minute, datediff(minute,getdate(),@mydate2),getutcdate())

1

रॉन के उत्तर में एक त्रुटि है। यह 2:00 बजे स्थानीय समय का उपयोग करता है जहां यूटीसी समकक्ष की आवश्यकता होती है। मेरे पास रॉन के जवाब पर टिप्पणी करने के लिए पर्याप्त प्रतिष्ठा बिंदु नहीं हैं इसलिए एक सही संस्करण नीचे दिखाई देता है:

-- =============================================
-- 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

यह एक विशेषता है, बग नहीं :) अधिकांश संयुक्त राज्य अमेरिका में डेलाइट सेविंग टाइम 2:00 am en.wikipedia.org/wiki/Daylight_saving_time
Ron Smith

@ रॉनस्मिथ हाँ, स्थानीय समयानुसार, 2:00 बजे, जिसे हमें यह पता लगाने के लिए यूटीसी में बदलना होगा कि क्या दिया गया यूटीसी समय डीएसटी रेंज में है।
jlspublic

1

UNIX टाइमस्टैम्प केवल एक विशेष तिथि और यूनिक्स युग के बीच की सेकंड की संख्या है,

चयनित तिथि (सेकंड, {d '1970-01-01'}, GETDATE ()) // यह UNIX टाइमस्टैम्प को SQL सर्वर में लौटा देगा

आप स्थानीय ऑफ़सेट समय के लिए एक फ़ंक्शन बना सकते हैं यूनिक्स यूटीसी रूपांतरण का उपयोग करके देश ऑफसेट फ़ंक्शन को यूनिक्स टाइम स्टैम्प इन एसक्यूएल सर्वर


1

यह आसान है। Azure SQL सर्वर के लिए यह प्रयास करें:

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

स्थानीय SQL सर्वर के लिए:

SELECT CONVERT(datetime2, SWITCHOFFSET(CONVERT(datetimeoffset, gETDATE()), DATENAME(TzOffset, gETDATE() AT TIME ZONE 'Eastern Standard Time'))) FROM YourTable

1
डेलाइट बचत समय के दौरान इसके साथ क्या होता है (चूंकि समय क्षेत्र विशेष रूप से "पूर्वी मानक समय" कहता है)?
मार्क

1

Azure SQL और @@Version> = SQL Server 2016 उपयोगकर्ताओं के लिए, नीचे एक सरल फ़ंक्शन का उपयोग किया गया है AT TIME ZONE

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

मूल्यों के प्रकार जो @LocalTimeZoneले सकते हैं, कृपया इस लिंक पर जाएं या जाएंKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones


0

एक चेतावनी के रूप में - यदि आप निम्नलिखित का उपयोग करने जा रहे हैं (मिनट के बजाय मिलीसेकंड पर ध्यान दें):

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

ध्यान रखें कि DatedIFF भाग हमेशा एक ही नंबर नहीं लौटाएगा। इसलिए इसका उपयोग डेटसाइड्स से डेटटाइम्स की तुलना करने के लिए न करें।


0

मैंने पाया है कि यह फ़ंक्शन एक अलग तालिका या लूप का उपयोग करके अन्य समाधानों की तुलना में तेज़ है। यह सिर्फ एक बुनियादी मामला बयान है। यह देखते हुए कि अप्रैल और अक्टूबर के बीच के सभी महीनों में -4 घंटे की ऑफसेट (पूर्वी समय) होती है, हमें बस फ्रिंज दिनों के लिए कुछ और केस लाइनों को जोड़ने की आवश्यकता है। अन्यथा, ऑफसेट -5 घंटे है।

यह यूटीसी से पूर्वी समय में रूपांतरण के लिए विशिष्ट है, लेकिन अतिरिक्त समय क्षेत्र कार्यों को आवश्यकतानुसार जोड़ा जा सकता है।

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

यह डीएसटी के साथ सर्वर समय प्राप्त करने में सक्षम होना चाहिए

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

sysdatetimeoffset डीएसटी को ध्यान में रखता है

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

0

पहला कार्य: इतालवी समय क्षेत्र (+1, +2) के लिए कॉन्फ़िगर किया गया, दिनांक स्विच करें: मार्च और अक्टूबर के अंतिम रविवार, वर्तमान समय क्षेत्र और पैरामीटर के रूप में डेटाटाइम के बीच अंतर लौटाएं।

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

कोड है:

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

फिर फ़ंक्शन जो दिनांक परिवर्तित करता है

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

- utc से भारतीय मानक समय प्राप्त करें

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

    RETURN dateadd(minute,330,@UTCDate)

END
GO

0

यह एक फ़ंक्शन के बिना किया जा सकता है। नीचे दिया गया कोड दिन की बचत के लिए यूटीसी समय को माउंटेन टाइम अकाउंटिंग में बदल देगा। अपने समयक्षेत्र के अनुसार सभी -6 और -7 संख्याओं को समायोजित करें (अर्थात ईएसटी के लिए आप क्रमशः -4 और -5 में समायोजित करेंगे)

--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

0

आपको स्ट्रिंग को रिफॉर्म करने के साथ-साथ सही समय पर कंवर्ट करना होगा। इस मामले में मुझे ज़ुलु समय की आवश्यकता थी।

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

Oracle के लिए सबसे अच्छा तरीका:

हार्डकोडेड डेटटाइम के साथ:

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

स्तंभ और तालिका नामों के साथ:

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

मेरे पास UTC को स्थानीय और स्थानीय से UTC बार करने के लिए कोड है जो इस तरह कोड का उपयोग करके रूपांतरण की अनुमति देता है

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

तथा

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

कार्य IANA / TZDB में टाइमज़ोन के सभी या सबसेट का समर्थन कर सकते हैं, जैसा कि NodaTime द्वारा प्रदान किया गया है - पूरी सूची यहां देखें https://nodatime.org/TimeZones देखें

ध्यान रखें कि मेरे उपयोग के मामले का मतलब है कि मुझे केवल 'करंट' विंडो की आवश्यकता है, जो अब तक के बारे में +/- 5 साल के भीतर समय के रूपांतरण की अनुमति देता है। इसका मतलब यह है कि मैंने जिस विधि का उपयोग किया है वह संभवतः आपके लिए उपयुक्त नहीं है यदि आपको एक बहुत विस्तृत अवधि की आवश्यकता है, जिस तरह से यह एक निश्चित तिथि सीमा में प्रत्येक टाइमज़ोन अंतराल के लिए कोड उत्पन्न करता है।

यह परियोजना GitHub: https://github.com/elliveny/SQLServerTimeConversion पर है

इस उदाहरण के अनुसार SQL फ़ंक्शन कोड उत्पन्न करता है


0

ठीक है अगर आप डेटाबेस में यूटीसी तिथि के रूप में डेटा संग्रहीत करते हैं तो आप कुछ सरल के रूप में कर सकते हैं

select 
 [MyUtcDate] + getdate() - getutcdate()
from [dbo].[mytable]

यह सर्वर के बिंदु से हमेशा स्थानीय था और आप एटी के साथ लड़खड़ा नहीं रहे हैं TIME ZONE 'your time zone name', यदि आपका डेटाबेस किसी अन्य समय क्षेत्र में स्थानांतरित हो जाता है जैसे कि क्लाइंट इंस्टॉलेशन एक हार्ड कोडित समय क्षेत्र आपको काट सकता है।


0

पोस्टग्रैज में यह बहुत अच्छी तरह से काम करता है..इस सर्वर को उस समय बताएं, जिस समय का समय बचा है, 'utc', और फिर इसे एक विशिष्ट टाइमज़ोन में बदलने के लिए कहें, इस मामले में 'ब्राज़ील / ईस्ट'

quiz_step_progresses.created_at  at time zone 'utc' at time zone 'Brazil/East'

निम्नलिखित चयन के साथ टाइमज़ोन की पूरी सूची प्राप्त करें;

select * from pg_timezone_names;

विवरण यहाँ देखें।

https://popsql.com/learn-sql/postgresql/how-to-convert-utc-to-local-time-zone-in-postgresql


-1

यहाँ एक सरल है कि खाते में dst लेता है

CREATE FUNCTION [dbo].[UtcToLocal] 
(
    @p_utcDatetime DATETIME 
)
RETURNS DATETIME
AS
BEGIN
    RETURN DATEADD(MINUTE, DATEDIFF(MINUTE, GETUTCDATE(), @p_utcDatetime), GETDATE())
END

6
यह वास्तव में डीएसटी को ध्यान में नहीं रखता है। बस इसे आज़माएँ SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, GETUTCDATE(), '20150101'), GETDATE()):। मैं वर्तमान में CEST (UTC + 2) में हूं, लेकिन DST नए साल के दिन प्रभावी नहीं होगा, इसलिए मेरे लिए सही उत्तर 1 जनवरी 2015 01:00 होगा। आपका उत्तर, स्वीकृत उत्तर की तरह, 1 जनवरी 2015 02:00 से वापस आता है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.