নির্বাচন বিবরণীতে ডেটটাইম কলামটি ইউটিসি থেকে স্থানীয় সময় রূপান্তর করুন


208

আমি কয়েকটি এসকিউএল নির্বাচন করে জিজ্ঞাসা করছি এবং আমার জিজ্ঞাসার ফলাফলগুলিতে স্থানীয় সময় হিসাবে প্রদর্শিত হতে আমার ইউটিসি ডেটটাইম কলাম স্থানীয় সময় রূপান্তর করতে চাই। দ্রষ্টব্য, আমি কোডের মাধ্যমে এই রূপান্তরটি করতে চাইছি না বরং আমি যখন আমার ডাটাবেসের বিরুদ্ধে ম্যানুয়াল এবং এলোমেলো এসকিউএল অনুসন্ধানগুলি করছি তখন।


এই প্রশ্নটি কি আপনার পরিস্থিতিগুলির সাথে মিল রয়েছে? stackoverflow.com/questions/3404646/…
তারিন পূর্ব

উত্তর:


322

আপনি এসকিউএল সার্ভার ২০০৮ বা তার চেয়ে বেশি এর উপর নিম্নলিখিত হিসাবে এটি করতে পারেন:

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

আপনি যা-ই করুন না কেন, তারিখগুলি বিয়োগ করতে ব্যবহার করবেন না- , কারণ অপারেশনটি পারমাণবিক নয় এবং আপনি বিভিন্ন সময় সিস্টেমের ডেটটাইম এবং স্থানীয় তারিখের সময় বিভিন্ন সময়ে পরীক্ষা করা হওয়ার কারণে (যেমন, অ-পরমাণুরূপে) পরীক্ষা করার জন্য অনির্দিষ্ট ফলাফল পেতে পারেন you ।

দয়া করে নোট করুন যে এই উত্তরটি ডিএসটি আমলে নেয় না। আপনি যদি কোনও ডিএসটি সমন্বয় অন্তর্ভুক্ত করতে চান তবে দয়া করে নীচের এসও প্রশ্নটি দেখুন:

এসকিউএল সার্ভারে কীভাবে ডাইটলাইট সেভিংস টাইম স্টার্ট এবং এন্ড ফাংশন তৈরি করবেন


38
দিনের হালকা সঞ্চয়ের জন্য এই অ্যাকাউন্টটি করার কোনও উপায় আছে কি?
স্টিভ

15
আমি এখানে কোনও টাইম জোনের নাম দেখছি না তাই এটি ভুল। গণিতের মাধ্যমে আপনি স্থানীয় সময় রূপান্তর করতে পারবেন এমন ধারণা করা সত্যিই খারাপ ধারণা
JonnyRaa

7
@ মাইকেল গল্ডশটায়েন আপনার যদি টাইমজোন অফসেট থাকে তবে আপনি এখনও জানেন না যে কোন সময়টি যৌক্তিক টাইমজোন রয়েছে তা টাইমজোনগুলি সামাজিক জিনিস এবং বিভিন্ন পয়েন্টে সরকার দ্বারা পরিবর্তন করা যেতে পারে। সময় / ইতিহাসের বিভিন্ন পয়েন্টে টাইমজোনটির জন্য অফসেটটি ভিন্ন হতে পারে (গ্রীষ্মের সময়টি একটি সাধারণ কারণ)। আপনি ইউটিসি থেকে বর্তমান অফসেট দিয়ে একটি সময় অফসেট করছেন ... আরও একটি বিষয় হ'ল এটি সার্ভারের টাইমজোন দেবে এবং ক্লায়েন্টকে নয়, আপনি অন্য দেশে হোস্টিংয়ের ক্ষেত্রে আরও সমস্যা হতে পারে।
JonnyRaa

4
@ নীলুফার এর সহজ উত্তরটি হ'ল আপনি করবেন না এবং করা উচিত নয়। তারিখের সময়গুলি সর্বদা ইউটিসিতে সংরক্ষণ করা উচিত (পছন্দসই ডাটাবেস সার্ভারের ঘড়ির উপর ভিত্তি করে, ওয়েব সার্ভারের নয়, অ্যাপ্লিকেশন সার্ভারের, এবং অবশ্যই ক্লায়েন্টের ঘড়ি নয়)। তারিখের সময়টি প্রদর্শন করা ইউআই স্তরের জন্য একটি ফাংশন এবং ডেটটাইমটি আপনি যে ফর্ম্যাটটিতে চান তা রূপান্তর করার জন্য দায়ী (প্রয়োজনে টাইমজোন সহ)।
রবার্ট ম্যাককি

11
স্কেল আজেউর ব্যবহারকারী যে কোনও ব্যক্তির পক্ষে এই পদ্ধতির কাজ হবে না কারণ তারিখ / সময় ফাংশনগুলি সমস্ত ইউটিসি ফিরিয়ে দেয়, সুতরাং GETDATE () কে GETUTCDATE () এর সাথে তুলনা করলে আপনাকে কোনও কাজ করার সুযোগ দেয় না এবং আপনার ফলাফলটি আপনি যেমন শুরু করেছিলেন ঠিক তেমনই।
ব্রায়ান সুরোইইক

59

নির্দিষ্ট সময় অঞ্চলটিতে ইউটিসি হিসাবে একটি ডেটটাইম সঞ্চিত একটি ডেটটাইম (সার্ভারের টাইমজোন নয় কারণ অ্যাজুরি এসকিউএল ডাটাবেসগুলি ইউটিসি হিসাবে চালিত হয়) পাওয়ার জন্য এই উদাহরণগুলির মধ্যে আমি কোনও খুঁজে পাইনি। এইভাবেই আমি এটি পরিচালনা করেছি। এটি মার্জিত নয় তবে এটি সহজ এবং অন্যান্য সারণী রক্ষণাবেক্ষণ না করে আপনাকে সঠিক উত্তর দেয়:

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

4
কেবলমাত্র 2016 এর জন্য কাজ করে এবং সিস্টেম রেজিস্ট্রি ব্যবহার করে। তবে আজুরের জন্য দুর্দান্ত সমাধান।
ড্যান কান্দি

2
এটি ইউটিসিতে সঞ্চিত আযুর সময়গুলির জন্য কাজ করে, ধন্যবাদ ছেলেরা
নুল

3
আপনি সময় অঞ্চলগুলির জন্য যে স্ট্রিংগুলি ব্যবহার করতে পারেন তার একটি তালিকা এখানে রয়েছে: stackoverflow.com/a/7908482/631277
ম্যাট কেম্প

1
যদি এসকিউএল 2016 এবং AT TIME ZONEসিনট্যাক্স ব্যবহার করে থাকেন তবে স্ট্যাকওভারফ্লো.com / a / 44941536 / 112764 বিবেচনা করুন - আপনি কেবল একাধিক এসকে একত্রিত করে একাধিক রূপান্তরকে এক সাথে চেইন করতে পারেন at time zone <blah>
নাটজে

3
এটিও কিছুটা অদ্ভুত, তবে কিছু খুব প্রাথমিক টেস্টিং দেখে মনে হচ্ছে dateTimeField AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time'এটি কার্যকরও হতে পারে - - কেবল AT TIME ZONEবিবৃতি শৃঙ্খলাবদ্ধ । (@ নাটজে এটি উপরে উল্লিখিত আমি এখন দেখতে পাচ্ছি)
ডেভিড মোহুন্দ্রো

22

যদি আপনার স্থানীয় তারিখের সময় বলা হয় Eastern Standard Timeএবং আপনি ইউটিসি থেকে সেই রূপান্তর করতে চান, তবে অ্যাজুরে এসকিউএল এবং এসকিউএল সার্ভার 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
এসএমএল সার্ভারে টাইমজোনস এবং অফসেটগুলিও এখানে পাওয়া যাবে:
সিএসএইচ

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' ডিএসটি পরিসর প্রাপ্তিতে প্রতিনিধিত্ব করে। এটি হার্ড কোডড দিন হিসাবে দেখা যায় যা ডিটিএসের কারণে পরিবর্তিত হয়। কেন আপনি এটি হার্ড কোড করবেন যখন এটি গণনার তারিখ হওয়া উচিত কারণ ক্যালেন্ডারে কোথায় মার্চের দ্বিতীয় রবিবার এবং নভেম্বরের প্রথম রবিবার আসে তার উপর ভিত্তি করে দিনগুলি পরিবর্তিত হয়। কঠোর কোডড দিনগুলি এই কোডটি মূলত ত্রুটিযুক্ত করবে।
মাইক

2
ভাল প্রশ্ন :) এগুলি সর্বাধিক তারিখ যেখানে মার্চের দ্বিতীয় রবিবার এবং নভেম্বর মাসে প্রথম রবিবার হতে পারে occur নিম্নলিখিত লাইনগুলি ভেরিয়েবলগুলি আসল তারিখে সেট করে।
রন স্মিথ

8

নতুন এসকিউএল সার্ভার 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 গুণ দ্রুত কাজ করে: '- (

মনোযোগ দিন যে এক টাইম জোনের জন্য অফসেট শীত বা গ্রীষ্মের সময়গুলিতে পরিবর্তিত হতে পারে। উদাহরণ স্বরূপ

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

একটি ইউটিসি ডেটটাইম মান চলে যায় এবং সার্ভারের সাথে সম্পর্কিত স্থানীয় ডেটটাইম মান বেরিয়ে আসে। নাল মানগুলি নালায় ফিরে আসে।


5

সঠিক এবং জেনেরিক উপায়ে এটি করার সহজ কোনও উপায় নেই।

সবার আগে এটি অবশ্যই বুঝতে হবে যে অফসেটটি প্রশ্নে থাকা তারিখ, সময় অঞ্চল এবং ডিএসটি-র উপর নির্ভর করে। GetDate()-GetUTCDateকেবলমাত্র আজ আপনাকে সার্ভারের টিজেডে অফসেট দেয় যা প্রাসঙ্গিক নয়।

আমি মাত্র দুটি কার্যনির্বাহী সমাধান দেখেছি এবং আমার অনেক অনুসন্ধান রয়েছে।

1) টিজেডে টাইম জোনস এবং ডিএসটি নিয়মের মতো বেস ডেটা টেবিলগুলির সাথে কয়েকটা টেবিল সহ একটি কাস্টম এসকিউএল ফাংশন। কাজ কিন্তু খুব মার্জিত না। আমি কোডটির মালিক না হওয়ায় এটি পোস্ট করতে পারি না।

সম্পাদনা: এখানে এই পদ্ধতির উদাহরণ https://gist.github.com/drumsta/16b79cee6bc195cd89c8

2) ডিবিতে। নেট অ্যাসেম্বলি যুক্ত করুন, নেট এটি খুব সহজেই করতে পারে। এটি খুব ভালভাবে কাজ করছে তবে খারাপ দিকটি হ'ল আপনাকে সার্ভার স্তরে বেশ কয়েকটি পরামিতি কনফিগার করতে হবে এবং কনফিগারেশনটি সহজেই নষ্ট হয়ে গেছে যেমন আপনি যদি ডাটাবেস পুনরুদ্ধার করেন। আমি এই পদ্ধতিটি ব্যবহার করি তবে কোডটির মালিক না হওয়ায় আমি এটি পোস্ট করতে পারি না।


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())
টম ওয়ারফিল্ড

আমার আগের সাগ্রহে অনুসরণ করা - আপনি যদি @ স্ট্যান্ডার্ডঅফসেট গণনা করেন তবে আপনাকে ডিএসটি সংশোধন করার দরকার নেই।
টম ওয়ারফিল্ড

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

@ ভিকজোন0 হ্যাঁ, আমি এটির জন্য যে প্রকল্পটি তৈরি করেছি তাতে কেবল মার্কিন সময় অঞ্চল ছিল।
জেব্রুকস

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

1

রনের উত্তরে একটি ত্রুটি রয়েছে। এটি স্থানীয় সময় 2:00 AM ব্যবহার করে যেখানে ইউটিসি সমতুল্য প্রয়োজন। রনের উত্তরে মন্তব্য করার মতো পর্যাপ্ত খ্যাতি পয়েন্ট আমার কাছে নেই তাই নীচে একটি সংশোধিত সংস্করণ উপস্থিত হবে:

-- =============================================
-- 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 টায় শুরু করে en.wikedia.org/wiki/Daylight_s बचत_
রন স্মিথ

@ রোনস্মিথ হ্যাঁ, স্থানীয় সময় সকাল ২ টা ৪০ মিনিটে, প্রদত্ত ইউটিসি সময়টি ডিএসটি পরিসরে রয়েছে কিনা তা সনাক্ত করতে আমাদের ইউটিসিতে রূপান্তর করতে হবে।
jlspublic

1

ইউনিক্স টাইমস্ট্যাম্পটি নির্দিষ্ট তারিখ এবং ইউনিক্সের যুগের মধ্যে কেবল সেকেন্ডের সংখ্যা,

তারিখটি নির্বাচন করুন (সেকেন্ড, 'ডি' 1970-01-01 '}, GETDATE ()) // এটি এসকিউএল সার্ভারে ইউনিক্স টাইমস্ট্যাম্পটি ফিরিয়ে দেবে

আপনি এসকিউএল সার্ভারে ইউনিক্স টাইম স্ট্যাম্পে কান্ট্রি অফসেট ফাংশন ব্যবহার করে ইউনিক্স ইউটিসি রূপান্তর করতে স্থানীয় তারিখের জন্য একটি ফাংশন তৈরি করতে পারেন


1

ইহা সহজ. অ্যাজুর এসকিউএল সার্ভারের জন্য এটি ব্যবহার করে দেখুন:

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

স্থানীয় এসকিউএল সার্ভারের জন্য:

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

1
দিবালোক সঞ্চয় সময় (সময় অঞ্চলটি নির্দিষ্টভাবে "পূর্ব স্ট্যান্ডার্ড সময়" বলে) এর সাথে কী ঘটে?
চিহ্নিত করুন

1

আজুর এসকিউএল এবং @@Version> = এসকিউএল সার্ভার 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

মনে রাখবেন যে ডেটেডিএফ অংশটি সর্বদা একই সংখ্যা ফেরত দেয় না। সুতরাং এটি ডেটটাইমগুলি তুলনা করতে মিলিসেকেন্ডে ব্যবহার করবেন না।


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

- ইউটিসি থেকে ভারতীয় স্ট্যান্ডার্ড সময় পান

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

    RETURN dateadd(minute,330,@UTCDate)

END
GO

0

এটি কোনও ফাংশন ছাড়াই করা যায়। নীচের কোডটি একটি ইউটিসি সময়কে দিনের আলোর সঞ্চয়ের জন্য মাউন্টেন টাইম অ্যাকাউন্টে রূপান্তর করবে। আপনার টাইমজোন অনুসারে সমস্ত -6 এবং -7 নম্বরগুলি সামঞ্জস্য করুন (যেমন EST এর জন্য আপনি যথাক্রমে -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

ওরাকলের জন্য সেরা উপায়:

হার্ডকোডড ডেটটাইম সহ:

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

আমার কাছে ইউটিসি থেকে স্থানীয় এবং স্থানীয় থেকে ইউটিসি সময় সম্পাদন করার কোড রয়েছে যা এই জাতীয় কোড ব্যবহার করে রূপান্তর করতে দেয়

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)

ফাংশনগুলি নোডাটাইম দ্বারা প্রদত্ত আইএএনএ / টিজেডডিবি-তে সমস্ত অঞ্চল বা একটি উপসেটকে সমর্থন করতে পারে - https://nodatime.org/TimeZones এ সম্পূর্ণ তালিকা দেখুন

সচেতন থাকুন যে আমার ব্যবহারের ক্ষেত্রে এখন থেকে প্রায় +/- 5 বছর বয়সের মধ্যে সময়ের রূপান্তরকে অনুমতি দিয়ে আমার কেবল একটি 'বর্তমান' উইন্ডো দরকার। এর অর্থ হ'ল আমি যে পদ্ধতিটি ব্যবহার করেছি এটি সম্ভবত আপনার পক্ষে উপযুক্ত নয় যদি আপনার একটি নির্দিষ্ট তারিখের সীমাতে প্রতিটি টাইমজোন ব্যবধানের জন্য কোড তৈরি করে to

প্রকল্পটি গিটহাবটিতে রয়েছে: https://github.com/elliveny/SQLServerTimeConversion

এই উদাহরণ অনুসারে এটি এসকিউএল ফাংশন কোড উত্পন্ন করে


0

ওয়েল, আপনি ডাটাবেসে ইউটিসি তারিখ হিসাবে ডেটা সঞ্চয় করে রাখেন তবে আপনি কিছু সহজ করতে পারেন

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

সার্ভারের দিক থেকে এটি সর্বদা স্থানীয় ছিল এবং আপনি এটি-তে ভ্রান্ত হন না TIME ZONE 'your time zone name', যদি আপনার ডাটাবেসটি ক্লায়েন্টের মতো অন্য একটি টাইম জোনে সরিয়ে নিয়ে যায় তবে কোনও হার্ড কোডিং টাইম অঞ্চল আপনাকে কামড়ায়।


0

পোস্টগ্রিসে এটি খুব সুন্দরভাবে কাজ করে .. সার্ভারটি যে সময়টি বাঁচানো হয় তার সময় বলুন, 'ইউটিসি', এবং তারপরে একটি নির্দিষ্ট সময় অঞ্চলে রূপান্তর করতে বলুন, এই ক্ষেত্রে 'ব্রাজিল / পূর্ব'

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

এখানে অ্যাকাউন্টে ডিস্টে নেয় এমন একটি সহজ

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())। আমি বর্তমানে সিইএসটি (ইউটিসি +২) এ আছি, তবে ডিএসটি নববর্ষের দিনে কার্যকর হবে না, তাই আমার জন্য সঠিক উত্তরটি হবে 1 জানুয়ারী 2015 01:00। আপনার উত্তর, গৃহীত উত্তরের মতো, 1 জানুয়ারী 2015 02:00 এ ফিরে আসে।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.