কীভাবে আমি এসকিউএল সার্ভারে বিগিন্ট (ইউনিক্স টাইমস্ট্যাম্প) ডেটটাইমে রূপান্তর করতে পারি?


104

কীভাবে আমি ইউনিক্স টাইমস্ট্যাম্প (বিগিন্ট) কে এসকিউএল সার্ভারে ডেটটাইমে রূপান্তর করতে পারি?

উত্তর:


57

চেষ্টা করে দেখুন:

CREATE FUNCTION dbo.fn_ConvertToDateTime (@Datetime BIGINT)
RETURNS DATETIME
AS
BEGIN
    DECLARE @LocalTimeOffset BIGINT
           ,@AdjustedLocalDatetime BIGINT;
    SET @LocalTimeOffset = DATEDIFF(second,GETDATE(),GETUTCDATE())
    SET @AdjustedLocalDatetime = @Datetime - @LocalTimeOffset
    RETURN (SELECT DATEADD(second,@AdjustedLocalDatetime, CAST('1970-01-01 00:00:00' AS datetime)))
END;
GO

2
ইউটিসি-> স্থানীয় রূপান্তরকরণের জন্য +1। নোট করুন যে আপনি গ্রীষ্ম / শীতকালীন সময়টি এখনও বন্ধ থাকবে যদি আপনি ফেব্রুয়ারিতে 10 ই জুন অনুবাদ করতে চেষ্টা করেন।
Andomar

11
ইউটিসি-> স্থানীয় রূপান্তরকরণের জন্য -1। এটি দিবালোক সংরক্ষণের সময়টি সঠিকভাবে পরিচালনা করছে না। আমার জন্য, এটি বিভ্রান্তিকর।
পাভেল হোরাল

সৃজনশীল সমাধানের জন্য +1! দুর্দান্ত কাজ করে। এফওয়াইআই, এসকিউএলে একটি সিনট্যাক্স ত্রুটি রয়েছে। প্রথম "DECLARE" রেখার শেষে আধা-কোলনটি মুছার পরে কমাটি অনুসরণ করা দরকার।
শেঠ

2
এটি আমার পক্ষে কাজ করে না। আমি এটি 1517270400000 দিয়ে চেষ্টা করছি এবং এই ত্রুটিটি পেয়েছি: গাণিতিক ওভারফ্লো ত্রুটি এক্সপ্রেশনটিকে ডেটা টাইপ ইনটে রূপান্তর করে।
ডেনিশ

1
একটি ওভারফ্লোও পেয়ে যাচ্ছিল, সাধারণত এর অর্থ মিলিসেকেন্ডগুলি জড়িত রয়েছে, সহজভাবে সমাধান করা হয়েছে: src_table থেকে dbo.fn_ConvertToDateTime (src_column / 1000) নির্বাচন করুন;
অ্যাক্সেস_গ্রন্থ

304

এটি আমার পক্ষে কাজ করেছে:

Select
    dateadd(S, [unixtime], '1970-01-01')
From [Table]

যদি কেউ কেউ অবাক হয় কেন 1970-01-01, এটিকে ইপোক টাইম বলা হয়

নীচে উইকিপিডিয়া থেকে একটি উদ্ধৃতি দেওয়া হয়েছে:

১৯০ 1970 সালের ১ জানুয়ারী সমন্বিত ইউনিভার্সাল টাইম (ইউটিসি), বৃহস্পতিবার, ১৯ 1970০ সাল থেকে সেকেন্ডের সংখ্যা কেটে গেছে [১] [নোট 1] লিপ সেকেন্ড গণনা করছে না।


17
এটি সঠিক হিসাবে চিহ্নিত করা উচিত। আমি আশা করি প্রতিবার আমি এখানে
পৌঁছানোর সাথে সাথে

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

1
আমি এই সমাধান ব্যবহার করা হয়। এই ফর্ম্যাটেড তারিখটি অন্যান্য ডেটার সাথে সংঘবদ্ধ ছিল, তাই আমার কাছে একটি ভার্চার ছিল ... সহজ! অ্যাপ্লিকেশনগুলিতে সেই লগগুলি ফর্ম্যাট করতে বিরক্ত করার দরকার নেই। তবে কিছু ওয়াইল্ড টাইম জোনের সমস্যা হাজির! আমার তারিখগুলি গ্রাহকের সময় অঞ্চলটির পরিবর্তে ইউটিসি সময় অঞ্চলটি ব্যবহার করছিল :(
গুস্তাভোহেঙ্কে

2
@ হোইটকেট জানেন না আপনি ইতিমধ্যে আপনার সমস্যার সমাধান করেছেন কিনা তবে কেসিং দেখুন! হতে পারে আপনার ডাটাবেস কোলেশন সেটিংস 'এসকিউএল_ল্যাটিন 1_ জেনারাল_সিপি 1_সিএস_এএস' এর মতো কিছুতে সেট করা আছে, সিএস এখানে কীওয়ার্ড। এটি "কেস সেনসিটিভ" এর জন্য দাঁড়িয়েছে যার জন্য আপনার কোডটি আবৃতের সাথে মেলে! আর একটি বিষয় হতে পারে যে নামটি তারিখ_যুদ্ধ () এর চেয়ে আপনার সিস্টেমটি মাইএসকিউএল। শুভেচ্ছা;)
রাত 11-15

3
এই সমাধানটি ২০৩৮ সালের সমস্যার দ্বারা প্রভাবিত হবে কারণ ডেটেড্ড ফাংশনটির জন্য একটি প্রকারের প্রয়োজন। ডকুমেন্টেশন বলছে "সংখ্যার আর্গুমেন্ট ইনট এর সীমা অতিক্রম করতে পারে না।" docs.microsoft.com/en-us/sql/t-sql/functions/... en.wikipedia.org/wiki/Year_2038_problem
প্যাট্রিক এইচ

29

যদি কেউ ত্রুটির নীচে পেয়ে থাকে:

গাণিতিক ওভারফ্লো ত্রুটি অভিব্যক্তিটিকে ডেটা টাইপ ইনটে রূপান্তর করে

ইউনিক্স টাইমস্ট্যাম্পের কারণে বিগিন্টে রয়েছে (ইনট এর পরিবর্তে), আপনি এটি ব্যবহার করতে পারেন:

SELECT DATEADD(S, CONVERT(int,LEFT(1462924862735870900, 10)), '1970-01-01')
FROM TABLE

আপনার প্রকৃত কলামের জন্য হার্ডকডযুক্ত টাইমস্ট্যাম্পটি ইউনিক্স-টাইমস্ট্যাম্পের সাথে প্রতিস্থাপন করুন

উত্স: এমএসএসকিউএল বিগিন্ট ইউনিক্স টাইমস্ট্যাম্পটি ডেটটাইম থেকে মিলিসেকেন্ড সহ


ইউপ মিলিসেকেন্ডগুলি দেওয়া হয়েছে, আরও উন্নত: নির্বাচন করুন তারিখ (এমএস, 1517270454852% 1000, ডেটএইডিডিডি (এস, 1517270454852/1000, '1970-01-01'))
জি ডিমেস্টারস

25

এটার মত

সেকেন্ডে বেস তারিখটিতে ইউনিক্স (মহাকাশ) ডেটটাইম যুক্ত করুন

এটি আপাতত এটি পাবেন (2010-05-25 07: 56: 23.000)

 SELECT dateadd(s,1274756183,'19700101 05:00:00:000')

যদি আপনি বিপরীতে যেতে চান তবে এই http://wiki.lessthandot.com/index.php/Epoch_Date এ একবার দেখুন


1
কেন 00:00:00 এর পরিবর্তে 05:00:00?
Svisstack

2
@ সুইভস্ট্যাক 5 ঘন্টা সময় অঞ্চল পার্থক্য জন্য। 5:00:00 এর অর্থ তিনি GMT-5 ঘন্টা
জর্ডি ভ্যান আইজক

একটি যাদুমন্ত্র মত কাজ করে. আপনার যদি
টাইমজোনটির

7

এটি এটি করবে:

declare @UNIX_TIME int
select @UNIX_TIME = 1111111111
-- Using dateadd to add seconds to 1970-01-01
select [Datetime from UNIX Time] = dateadd(!precision!,@UNIX_TIME,'1970-01-01')

পরিবর্তে! ব্যবহার: টাইমস্ট্যাম্পের যথার্থতা অনুসারে এস এস, এমএস বা এমসিএস। বিগিন্ট মাইক্রোসেকেন্ড যথার্থতা ধরে রাখতে সক্ষম।



4

যোগ করার পদ্ধতি এন সেকেন্ড 1970-01-01আপনি একটি দেব ইউটিসি তারিখ কারণ এন , ইউনিক্স টাইমস্ট্যাম্প হল সেকেন্ডের সংখ্যা যে যেহেতু 00:00:00 সমন্বয়িত ইউনিভার্সাল টাইম (UTC) অতিবাহিত করেছি, বৃহস্পতিবার, 1 জানুয়ারি 1970

এসকিউএল সার্ভার ২০১ 2016-তে আপনি একটি সময় অঞ্চলকে ব্যবহার করে অন্য একটিতে রূপান্তর করতে পারেন AT TIME ZONE। উইন্ডোজ স্ট্যান্ডার্ড ফর্ম্যাটে আপনাকে কেবল সময় অঞ্চলটির নাম জানতে হবে:

SELECT *
FROM (VALUES (1514808000), (1527854400)) AS Tests(UnixTimestamp)
CROSS APPLY (SELECT DATEADD(SECOND, UnixTimestamp, '1970-01-01') AT TIME ZONE 'UTC') AS CA1(UTCDate)
CROSS APPLY (SELECT UTCDate AT TIME ZONE 'Pacific Standard Time') AS CA2(LocalDate)
| UnixTimestamp | UTCDate                    | LocalDate                  |
|---------------|----------------------------|----------------------------|
| 1514808000    | 2018-01-01 12:00:00 +00:00 | 2018-01-01 04:00:00 -08:00 |
| 1527854400    | 2018-06-01 12:00:00 +00:00 | 2018-06-01 05:00:00 -07:00 |

বা সহজভাবে:

SELECT *, DATEADD(SECOND, UnixTimestamp, '1970-01-01') AT TIME ZONE 'UTC' AT TIME ZONE 'Pacific Standard Time'
FROM (VALUES (1514808000), (1527854400)) AS Tests(UnixTimestamp)
| UnixTimestamp | LocalDate                  |
|---------------|----------------------------|
| 1514808000    | 2018-01-01 04:00:00 -08:00 |
| 1527854400    | 2018-06-01 05:00:00 -07:00 |

মন্তব্য:

  • আপনি কাস্ট করে সময় অঞ্চল তথ্য কাটাতে DATETIMEOFFSETপারেন DATETIME
  • রূপান্তরটি অ্যাকাউন্টে দিবালোকের সঞ্চয় সময় নেয়। প্রশান্ত মহাসাগরীয় সময়টি ইউটিসি -08: 00 জানুয়ারী 2018 এবং জুন 2018 এ ইউটিসি -07: 00 ছিল।

3

যদি সময়টি মিলি সেকেন্ডে থাকে এবং সেগুলি সংরক্ষণের প্রয়োজন:

DECLARE @value VARCHAR(32) = '1561487667713';

SELECT DATEADD(MILLISECOND, CAST(RIGHT(@value, 3) AS INT) - DATEDIFF(MILLISECOND,GETDATE(),GETUTCDATE()), DATEADD(SECOND, CAST(LEFT(@value, 10) AS INT), '1970-01-01T00:00:00'))

1

এটি ড্যানিয়েল লিটল এই প্রশ্নের জন্য কাজটি বন্ধ করে দিচ্ছে, তবে দিবালোকের সঞ্চয় সময় বিবেচনায় নেওয়া (তারিখের জন্য কাজ করে ১৯০১-১০২০ এবং ডেটডিড ফাংশনের সীমাবদ্ধতার কারণে আরও বেশি):

আমাদের প্রথমে একটি টেবিল তৈরি করতে হবে যা দিবালোকের সঞ্চয় সময়ের জন্য তারিখের সীমা সংরক্ষণ করবে (উত্স: মার্কিন যুক্তরাষ্ট্রের সময়ের ইতিহাস ):

CREATE TABLE [dbo].[CFG_DAY_LIGHT_SAVINGS_TIME](
  [BEGIN_DATE] [datetime] NULL,
  [END_DATE] [datetime] NULL,
  [YEAR_DATE] [smallint] NULL
) ON [PRIMARY]

GO

INSERT INTO CFG_DAY_LIGHT_SAVINGS_TIME VALUES
('2001-04-01 02:00:00.000',   '2001-10-27 01:59:59.997',    2001),
('2002-04-07 02:00:00.000',   '2002-10-26 01:59:59.997',    2002),
('2003-04-06 02:00:00.000',   '2003-10-25 01:59:59.997',    2003),
('2004-04-04 02:00:00.000',   '2004-10-30 01:59:59.997',    2004),
('2005-04-03 02:00:00.000',   '2005-10-29 01:59:59.997',    2005),
('2006-04-02 02:00:00.000',   '2006-10-28 01:59:59.997',    2006),
('2007-03-11 02:00:00.000',   '2007-11-03 01:59:59.997',    2007),
('2008-03-09 02:00:00.000',   '2008-11-01 01:59:59.997',    2008),
('2009-03-08 02:00:00.000',   '2009-10-31 01:59:59.997',    2009),
('2010-03-14 02:00:00.000',   '2010-11-06 01:59:59.997',    2010),
('2011-03-13 02:00:00.000',   '2011-11-05 01:59:59.997',    2011),
('2012-03-11 02:00:00.000',   '2012-11-03 01:59:59.997',    2012),
('2013-03-10 02:00:00.000',   '2013-11-02 01:59:59.997',    2013),
('2014-03-09 02:00:00.000',   '2014-11-01 01:59:59.997',    2014),
('2015-03-08 02:00:00.000',   '2015-10-31 01:59:59.997',    2015),
('2016-03-13 02:00:00.000',   '2016-11-05 01:59:59.997',    2016),
('2017-03-12 02:00:00.000',   '2017-11-04 01:59:59.997',    2017),
('2018-03-11 02:00:00.000',   '2018-11-03 01:59:59.997',    2018),
('2019-03-10 02:00:00.000',   '2019-11-02 01:59:59.997',    2019),
('2020-03-08 02:00:00.000',   '2020-10-31 01:59:59.997',    2020),
('2021-03-14 02:00:00.000',   '2021-11-06 01:59:59.997',    2021),
('2022-03-13 02:00:00.000',   '2022-11-05 01:59:59.997',    2022),
('2023-03-12 02:00:00.000',   '2023-11-04 01:59:59.997',    2023),
('2024-03-10 02:00:00.000',   '2024-11-02 01:59:59.997',    2024),
('2025-03-09 02:00:00.000',   '2025-11-01 01:59:59.997',    2025),
('1967-04-30 02:00:00.000',   '1967-10-29 01:59:59.997',    1967),
('1968-04-28 02:00:00.000',   '1968-10-27 01:59:59.997',    1968),
('1969-04-27 02:00:00.000',   '1969-10-26 01:59:59.997',    1969),
('1970-04-26 02:00:00.000',   '1970-10-25 01:59:59.997',    1970),
('1971-04-25 02:00:00.000',   '1971-10-31 01:59:59.997',    1971),
('1972-04-30 02:00:00.000',   '1972-10-29 01:59:59.997',    1972),
('1973-04-29 02:00:00.000',   '1973-10-28 01:59:59.997',    1973),
('1974-01-06 02:00:00.000',   '1974-10-27 01:59:59.997',    1974),
('1975-02-23 02:00:00.000',   '1975-10-26 01:59:59.997',    1975),
('1976-04-25 02:00:00.000',   '1976-10-31 01:59:59.997',    1976),
('1977-04-24 02:00:00.000',   '1977-10-31 01:59:59.997',    1977),
('1978-04-30 02:00:00.000',   '1978-10-29 01:59:59.997',    1978),
('1979-04-29 02:00:00.000',   '1979-10-28 01:59:59.997',    1979),
('1980-04-27 02:00:00.000',   '1980-10-26 01:59:59.997',    1980),
('1981-04-26 02:00:00.000',   '1981-10-25 01:59:59.997',    1981),
('1982-04-25 02:00:00.000',   '1982-10-25 01:59:59.997',    1982),
('1983-04-24 02:00:00.000',   '1983-10-30 01:59:59.997',    1983),
('1984-04-29 02:00:00.000',   '1984-10-28 01:59:59.997',    1984),
('1985-04-28 02:00:00.000',   '1985-10-27 01:59:59.997',    1985),
('1986-04-27 02:00:00.000',   '1986-10-26 01:59:59.997',    1986),
('1987-04-05 02:00:00.000',   '1987-10-25 01:59:59.997',    1987),
('1988-04-03 02:00:00.000',   '1988-10-30 01:59:59.997',    1988),
('1989-04-02 02:00:00.000',   '1989-10-29 01:59:59.997',    1989),
('1990-04-01 02:00:00.000',   '1990-10-28 01:59:59.997',    1990),
('1991-04-07 02:00:00.000',   '1991-10-27 01:59:59.997',    1991),
('1992-04-05 02:00:00.000',   '1992-10-25 01:59:59.997',    1992),
('1993-04-04 02:00:00.000',   '1993-10-31 01:59:59.997',    1993),
('1994-04-03 02:00:00.000',   '1994-10-30 01:59:59.997',    1994),
('1995-04-02 02:00:00.000',   '1995-10-29 01:59:59.997',    1995),
('1996-04-07 02:00:00.000',   '1996-10-27 01:59:59.997',    1996),
('1997-04-06 02:00:00.000',   '1997-10-26 01:59:59.997',    1997),
('1998-04-05 02:00:00.000',   '1998-10-25 01:59:59.997',    1998),
('1999-04-04 02:00:00.000',   '1999-10-31 01:59:59.997',    1999),
('2000-04-02 02:00:00.000',   '2000-10-29 01:59:59.997',    2000)
GO

এখন আমরা প্রতিটি আমেরিকান টাইমজোন জন্য একটি ফাংশন তৈরি। এটি ধরে নিচ্ছে ইউনিক্স সময়টি মিলি সেকেন্ডে রয়েছে। যদি এটি সেকেন্ডের মধ্যে হয়, কোড থেকে / 1000 সরিয়ে ফেলুন:

শান্তিপ্রয়াসী

create function [dbo].[UnixTimeToPacific] 
 (@unixtime bigint)
   returns datetime
   as
   begin
     declare @pacificdatetime datetime
     declare @interimdatetime datetime = dateadd(s, @unixtime/1000, '1970-01-01')
     select  @pacificdatetime =  dateadd(hour,case when @interimdatetime between begin_date and end_date then -7 else -8 end  ,@interimdatetime)
     from cfg_day_light_savings_time  where  year_date = datepart(year,@interimdatetime)
     if @pacificdatetime is null 
       select @pacificdatetime= dateadd(hour, -7, @interimdatetime)
return @pacificdatetime    
end

পূর্ব

create function [dbo].[UnixTimeToEastern] 
 (@unixtime bigint)
   returns datetime
   as
   begin
     declare @easterndatetime datetime
     declare @interimdatetime datetime = dateadd(s, @unixtime/1000, '1970-01-01')
     select  @easterndatetime =  dateadd(hour,case when @interimdatetime between begin_date and end_date then -4 else -5 end  ,@interimdatetime)
     from cfg_day_light_savings_time  where  year_date = datepart(year,@interimdatetime)
     if @easterndatetime is null 
       select @easterndatetime= dateadd(hour, -4, @interimdatetime)
return @easterndatetime    
end

মধ্য

create function [dbo].[UnixTimeToCentral] 
 (@unixtime bigint)
   returns datetime
   as
   begin
     declare @centraldatetime datetime
     declare @interimdatetime datetime = dateadd(s, @unixtime/1000, '1970-01-01')
     select  @centraldatetime =  dateadd(hour,case when @interimdatetime between begin_date and end_date then -5 else -6 end  ,@interimdatetime)
     from cfg_day_light_savings_time  where  year_date = datepart(year,@interimdatetime)
     if @centraldatetime is null 
       select @centraldatetime= dateadd(hour, -5, @interimdatetime)
return @centraldatetime    
end

পর্বত

create function [dbo].[UnixTimeToMountain] 
 (@unixtime bigint)
   returns datetime
   as
   begin
     declare @mountaindatetime datetime
     declare @interimdatetime datetime = dateadd(s, @unixtime/1000, '1970-01-01')
     select  @mountaindatetime =  dateadd(hour,case when @interimdatetime between begin_date and end_date then -6 else -7 end  ,@interimdatetime)
     from cfg_day_light_savings_time  where  year_date = datepart(year,@interimdatetime)
     if @mountaindatetime is null 
       select @mountaindatetime= dateadd(hour, -6, @interimdatetime)
return @mountaindatetime    
end

হাওয়াই

create function [dbo].[UnixTimeToHawaii] 
 (@unixtime bigint)
   returns datetime
   as
   begin
     declare @hawaiidatetime datetime
     declare @interimdatetime datetime = dateadd(s, @unixtime/1000, '1970-01-01')
     select  @hawaiidatetime =  dateadd(hour,-10,@interimdatetime)
     from cfg_day_light_savings_time  where  year_date = datepart(year,@interimdatetime)

return @hawaiidatetime    
end

অ্যারিজোনা

create function [dbo].[UnixTimeToArizona] 
 (@unixtime bigint)
   returns datetime
   as
   begin
     declare @arizonadatetime datetime
     declare @interimdatetime datetime = dateadd(s, @unixtime/1000, '1970-01-01')
     select  @arizonadatetime =  dateadd(hour,-7,@interimdatetime)
     from cfg_day_light_savings_time  where  year_date = datepart(year,@interimdatetime)

return @arizonadatetime    
end

আলাস্কা

create function [dbo].[UnixTimeToAlaska] 
 (@unixtime bigint)
   returns datetime
   as
   begin
     declare @alaskadatetime datetime
     declare @interimdatetime datetime = dateadd(s, @unixtime/1000, '1970-01-01')
     select  @alaskadatetime =  dateadd(hour,case when @interimdatetime between begin_date and end_date then -8 else -9 end  ,@interimdatetime)
     from cfg_day_light_savings_time  where  year_date = datepart(year,@interimdatetime)
     if @alaskadatetime is null 
       select @alaskadatetime= dateadd(hour, -8, @interimdatetime)
return @alaskadatetime    
end

1
//BIGINT UNIX TIMESTAMP CONVERSION upto Millisecond Accuracy
CREATE FUNCTION [dbo].[ConvertUnixTimestamp] (@Datetime [BIGINT]) RETURNS DATETIME
AS
BEGIN

    RETURN DATEADD(MILLISECOND, cast(@Datetime as bigint) % 1000, 
    DATEADD(SECOND, (cast(@Datetime as bigint) / 1000)%60, 
    DATEADD(MINUTE, ((cast(@Datetime as bigint) / 1000)/60)%60, 
    DATEADD(HOUR, ((cast(@Datetime as bigint) / 1000)/60)/60, '19700101'))))
END

1

আমাকেও এই সমস্যার মুখোমুখি হতে হয়েছিল। দুর্ভাগ্যক্রমে, কোন উত্তর (এখানে এবং কয়েক ডজন অন্যান্য পৃষ্ঠাগুলিতে) আমার কাছে সন্তোষজনক হয়নি, কারণ আমি কোথাও 32 বিট পূর্ণসংখ্যার জন্য 2038 সাল পেরিয়ে এখনও তারিখগুলিতে পৌঁছতে পারছি না।

একটি সমাধান যা আমার জন্য শেষ পর্যন্ত কাজ করেছিল তা floatভেরিয়েবলগুলি ব্যবহার করা ছিল , যাতে আমার কমপক্ষে একটি সর্বাধিক তারিখ থাকতে পারে 2262-04-11T23:47:16.854775849। তবুও, এটি সম্পূর্ণ datetimeডোমেনটি কভার করে না , তবে এটি আমার প্রয়োজনের জন্য যথেষ্ট এবং অন্যদেরকেও একই সমস্যার মুখোমুখি হতে সহায়তা করতে পারে।

-- date variables
declare @ts bigint; -- 64 bit time stamp, 100ns precision
declare @d datetime2(7) = GETUTCDATE(); -- 'now'
-- select @d = '2262-04-11T23:47:16.854775849'; -- this would be the max date

-- constants:
declare @epoch datetime2(7) = cast('1970-01-01T00:00:00' as datetime2(7));
declare @epochdiff int = 25567; -- = days between 1900-01-01 and 1970-01-01
declare @ticksofday bigint = 864000000000; -- = (24*60*60*1000*1000*10)

-- helper variables:
declare @datepart float;
declare @timepart float;
declare @restored datetime2(7);

-- algorithm:
select @ts = DATEDIFF_BIG(NANOSECOND, @epoch, @d) / 100; -- 'now' in ticks according to unix epoch
select @timepart = (@ts % @ticksofday) / @ticksofday; -- extract time part and scale it to fractional part (i. e. 1 hour is 1/24th of a day)
select @datepart = (@ts - @timepart) / @ticksofday; -- extract date part and scale it to fractional part
select @restored = cast(@epochdiff + @datepart + @timepart as datetime); -- rebuild parts to a datetime value

-- query original datetime, intermediate timestamp and restored datetime for comparison
select
  @d original,
  @ts unix64,
  @restored restored
;

-- example result for max date:
-- +-----------------------------+-------------------+-----------------------------+
-- | original                    | unix64            | restored                    |
-- +-----------------------------+-------------------+-----------------------------+
-- | 2262-04-11 23:47:16.8547758 | 92233720368547758 | 2262-04-11 23:47:16.8533333 |
-- +-----------------------------+-------------------+-----------------------------+

কিছু বিষয় বিবেচনা করার আছে:

  • আমার ক্ষেত্রে 100ns নির্ভুলতা হ'ল প্রয়োজনীয়তা, তবে এটি 64 বিট ইউনিক্স টাইমস্ট্যাম্পের মানক রেজোলিউশন বলে মনে হচ্ছে। আপনি যদি অন্য কোনও রেজোলিউশন ব্যবহার করেন, আপনাকে @ticksofdayসেই অনুযায়ী অ্যালগরিদমের প্রথম লাইনটি সামঞ্জস্য করতে হবে ।
  • আমি অন্যান্য সিস্টেমগুলি ব্যবহার করছি যা টাইম অঞ্চল ইত্যাদিতে তাদের সমস্যা রয়েছে এবং আমি খুঁজে পেলাম আমার জন্য সর্বোত্তম সমাধানটি সর্বদা ইউটিসি ব্যবহার করা হবে। আপনার প্রয়োজনের জন্য, এটি পৃথক হতে পারে।
  • 1900-01-01ইউনিক্স টাইমস্ট্যাম্পগুলির জন্য datetime2পর্বের ঠিক 1970-01-01একইর জন্য মূল তারিখ ।
  • floats আমাকে বছরের ২০৩৮-এর সমস্যা এবং পূর্ণসংখ্যার ওভারফ্লোগুলি এবং এ জাতীয় সমাধান করতে সহায়তা করেছে তবে মনে রাখবেন যে ভাসমান পয়েন্ট সংখ্যাগুলি খুব পারফর্মেন্ট না এবং সংখ্যক টাইমস্ট্যাম্পগুলির প্রসেসিংয়ে ধীর করতে পারে। এছাড়াও, রাউন্ডঅফ ত্রুটির কারণে ফ্লোটগুলি যথাযথতা হারাতে পারে, যেমন আপনি উপরের সর্বাধিক তারিখের উদাহরণের ফলাফলের তুলনায় দেখতে পাচ্ছেন (এখানে, ত্রুটিটি প্রায় 1.4425ms)।
  • অ্যালগরিদমের শেষ লাইনে একটি castালাই রয়েছে datetime। দুর্ভাগ্যক্রমে, সংখ্যার মানগুলি থেকে datetime2অনুমোদিত পর্যন্ত কোনও স্পষ্ট নিক্ষেপ নেই , তবে এটি সংখ্যাকে datetimeস্পষ্টভাবে কাস্ট করার অনুমতি দেওয়া হয় এবং এটি পরিবর্তিতভাবে স্পষ্টতই কাস্ট করা হয় datetime2। এটা সঠিক, এখন হতে পারে, কিন্তু SQL সার্ভার ভবিষ্যত সংস্করণে পরিবর্তন করতে পারেন: হয় একটি থাকবে dateadd_big()ফাংশন বা স্পষ্ট ঢালাই করার datetime2অনুমতি দেওয়া হবে বা স্পষ্ট ঢালাই datetimeঅননুমোদিত হবে, তাই এটি হয় ভঙ্গ করতে পারে অথবা আসতে পারে একটি সহজ উপায় কিছু দিন।

1

জিএমটি-র পক্ষে, এখানে সবচেয়ে সহজ উপায়:

Select dateadd(s, @UnixTime+DATEDIFF (S, GETUTCDATE(), GETDATE()), '1970-01-01')

0

উত্তম? এই ফাংশনটি ইউনিক্সটাইমকে মিলি সেকেন্ডে ডেটটাইমে রূপান্তর করে। এটি মিলি সেকেন্ড হারিয়েছে তবে ফিল্টারিংয়ের জন্য এটি এখনও খুব দরকারী।

CREATE FUNCTION [dbo].[UnixTimestampToGMTDatetime] 
(@UnixTimestamp bigint)
RETURNS datetime
AS
BEGIN
       DECLARE @GMTDatetime datetime
       select @GMTDatetime = 
       CASE
       WHEN dateadd(ss, @UnixTimestamp/1000, '1970-01-01') 
       BETWEEN 
           Convert(DATETIME, Convert(VARCHAR(4), Year(dateadd(ss, @UnixTimestamp/1000, '1970-01-01') )) + '-03-' + Convert(VARCHAR(2), (31 - (5 * Year(dateadd(ss, @UnixTimestamp/1000, '1970-01-01') )/4 + 4) % 7)) + ' 01:00:00', 20)
       AND
           Convert(DATETIME, Convert(VARCHAR(4), Year(dateadd(ss, @UnixTimestamp/1000, '1970-01-01') )) + '-10-' + Convert(VARCHAR(2), (31 - (5 * Year(dateadd(ss, @UnixTimestamp/1000, '1970-01-01') )/4 + 1) % 7)) + ' 02:00:00', 20)
       THEN Dateadd(hh, 1, dateadd(ss, @UnixTimestamp/1000, '1970-01-01'))
       ELSE Dateadd(hh, 0, dateadd(ss, @UnixTimestamp/1000, '1970-01-01'))
       END
RETURN @GMTDatetime    
END

0

সমাধান নিম্নলিখিত হতে পারে:

DECLARE @UnixTimeStamp bigint = 1564646400000 /*2019-08-01 11:00 AM*/

DECLARE @LocalTimeOffset bigint = DATEDIFF(MILLISECOND, GETDATE(), GETUTCDATE());
DECLARE @AdjustedTimeStamp bigint = @UnixTimeStamp - @LocalTimeOffset;
SELECT [DateTime] = DATEADD(SECOND, @AdjustedTimeStamp % 1000, DATEADD(SECOND, @AdjustedTimeStamp / 1000, '19700101'));

0

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

CAST(DATEADD(S, [UnixTimestamp], '1970-01-01') AT TIME ZONE 'UTC' AT TIME ZONE 'Pacific Standard Time' AS Datetime)

দ্রষ্টব্য: এই সমাধানটি কেবলমাত্র এসকিউএল সার্ভার 2016 এবং তারপরে (এবং অ্যাজুরি) কাজ করে।

একটি ফাংশন তৈরি করতে:

CREATE FUNCTION dbo.ConvertUnixTime (@input INT)
RETURNS Datetime
AS BEGIN
    DECLARE @Unix Datetime

    SET @Unix = CAST(DATEADD(S, @Input, '1970-01-01') AT TIME ZONE 'UTC' AT TIME ZONE 'Pacific Standard Time' AS Datetime)

    RETURN @Unix
END

আপনি যেমন ফাংশন কল করতে পারেন:

SELECT   dbo.ConvertUnixTime([UnixTimestamp])
FROM     YourTable
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.