【问题标题】:Convert date in millisecond to date以毫秒为单位的日期转换为日期
【发布时间】:2015-10-01 09:09:29
【问题描述】:

在我的表中,我有一列包含以毫秒为单位的日期,如下所示:

table a 
      dateinmili
      1440301846096 //first six month date 
      1443589721039 //second six month date

我将它用于我的 Android 设备,它运行良好。当我想在 SQL Server 的 PROCEDURE 中使用这个时间并将这个时间转换为人类时间(人类可以理解)和日期时,我遇到了问题。

我在伊朗,前六个 波斯日期 月 4.30 和后六个月使用 3.30 的 UTC 时间。

对于 PROCEDURE 中的转换日期,我使用以下代码:

CONVERT(nVARCHAR(10),DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), DATEADD(ss,dateinmili/1000,'1970-01-01')),8) as date 
DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), DATEADD(ss,dateinmili/1000,'1970-01-01')) as time

这是我的问题:

当我转换第二个六个月的日期和一年前六个月的注册日期时,我得到实时时间和转换时间之间的 1 小时差异。我知道那是因为

 DATEDIFF(mi, GETUTCDATE(), GETDATE())    

在调用它时返回 UTC 时间和本地时间不同的方法(在我的示例中返回 3:30 而不是 4:30 )但我不知道如何解决这个问题?

我可以添加包含当前 UTC 时间的列,但我正在寻找另一种方式。

更新

我看到了 this question,将 long 转换为 date 不是我的问题。
我的问题是在我的国家,UTC 时间在全年不是恒定的,并且在 3.30 和 4.30 之间变化,例如,我在前六个月(波斯六个月)注册了日期,如 1440271800000,现在将其转换为我们在第二个六个月(波斯语六个月)并使用此代码进行转换。

declare @unixTS bigint
set @unixTS = 1440271800000

select dateadd(ms, @unixTS%(3600*24*1000), 
    dateadd(day, @unixTS/(3600*24*1000), '1970-01-01 03:30:00.0')
)

我明白了

 2015-08-22 23:00:00.000     

但这不是正确的日期;正确的日期是:

2015-08-23 00:00:00.000

因为当时间注册 UTC 是 4.30 而不是 3.30 但知道我什么时候转换 UTC 是 3.30。

我希望 SQL 中有一个方法返回过去的 UTC 时间不同;我的意思是给它一个日期,然后返回与我的问题解决的本地时间和格林威治时间不同的那个时间。

希望你能理解我的问题。

【问题讨论】:

  • “日期以毫秒为单位”是什么意思?这通常是 Uni/Linux 时间戳,它是自特定时间以来的毫秒数,例如 1970 年 1 月 1 日。您需要知道基准时间(即 0 代表什么),才能处理此日期。如果这确实是 Unix 时间戳,则只需将毫秒数添加到基准日期即可。这些时间戳对应的日期是什么?
  • PS 没有“人类时间”,操作系统的不同部分可能对“相同”的事物使用不同的类型。 Unix 时间戳对于文件创建/修改日期是可以的,但它完全不适合表示任意日期,更不用说处理时区了

标签: sql-server sql-server-2008 date datetime


【解决方案1】:

在美国,我们在夏季有夏令时,在大多数地区,这意味着我们也不是与 UTC 的固定偏移量。旧版本的 MS Dynamics CRM 过去以 UTC 格式保存所有内容,因此当我们想以当地时间导出数据时,我们进行了类似的练习。我创建了一组 SQL 函数,它们将标准 GMT 偏移量和日期时间转换为我想要转换并确定是应用标准偏移量还是 DST 偏移量并返回本地日期时间。如果你的偏移量遵循一组规则,那么你可以修改这个:

    CREATE function [dbo].[DC_GMTtoLocal]
    (@OrigGMT datetime, 
@StandardOffset int)
RETURNS datetime
AS
BEGIN
DECLARE @RevDate datetime

set @RevDate = CASE dbo.DC_DaylightSavingTime_IsInEffect(@OrigGMT)
    WHEN 1 THEN DATEADD(hour, - @StandardOffset + 1, @OrigGMT) --  in DST
    ELSE DATEADD(hour, - @StandardOffset, @OrigGMT) -- Not In DST
    END

return @RevDate 
END


GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE function [dbo].[DC_DaylightSavingTime_IsInEffect]
(@DtTime datetime)
RETURNS tinyint
AS
BEGIN
DECLARE @DLSStart datetime
, @DLSEnd datetime
, @DLSActive tinyint

SET @DLSActive = 0
If DATEADD(YEAR,3,GETDATE()) > @DtTime 
BEGIN
    SET @DLSStart =(SELECT dbo.DC_GetDaylightSavingsTimeStart(CONVERT(varchar,DATEPART(YEAR,@DtTime))))
    SET @DLSEnd =(SELECT dbo.DC_GetDaylightSavingsTimeEnd(CONVERT(varchar,DATEPART(YEAR,@DtTime))))


    IF @DtTime BETWEEN @DLSStart AND @DLSEnd 
    BEGIN
        SET @DLSActive = 1 
    END
        --SET @DLSActive = 0
END

RETURN @DLSActive 
END

GO

CREATE function [dbo].[DC_GetDaylightSavingsTimeStart]
(@Year varchar(4))
RETURNS smalldatetime
as
--Start date: We evaluate the day of the week corresponding to the first day of the month and find the second Sunday of March using a Case statement 
begin
declare @DTSStartWeek smalldatetime, @DTSEndWeek smalldatetime
set @DTSStartWeek = '03/01/' + convert(varchar,@Year)
return case datepart(dw,@DTSStartWeek)
when 1 then 
dateadd(hour,170,@DTSStartWeek)
when 2 then
dateadd(hour,314,@DTSStartWeek)
when 3 then 
dateadd(hour,290,@DTSStartWeek)
when 4 then 
dateadd(hour,266,@DTSStartWeek)
when 5 then 
dateadd(hour,242,@DTSStartWeek)
when 6 then 
dateadd(hour,218,@DTSStartWeek)
when 7 then
dateadd(hour,194,@DTSStartWeek)
end
end


GO

CREATE function [dbo].[DC_GetDaylightSavingsTimeEnd]
(@Year varchar(4))
RETURNS smalldatetime
as
-- End date: We evaluate the day of the week corresponding to the first day of the month and find the first Sunday of March using a Case statement 
begin
declare @DTSEndWeek smalldatetime
set @DTSEndWeek = '11/01/' + convert(varchar,@Year)
return case datepart(dw,dateadd(week,1,@DTSEndWeek))
when 1 then
dateadd(hour,2,@DTSEndWeek)
when 2 then
dateadd(hour,146,@DTSEndWeek)
when 3 then
dateadd(hour,122,@DTSEndWeek)
when 4 then
dateadd(hour,98,@DTSEndWeek)
when 5 then 
dateadd(hour,74,@DTSEndWeek)
when 6 then 
dateadd(hour,50,@DTSEndWeek)
when 7 then 
dateadd(hour,26,@DTSEndWeek)
end
end


GO

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-27
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    • 2019-05-04
    • 1970-01-01
    相关资源
    最近更新 更多