我想将sql server datetime转换为毫秒。我尝试使用datediff函数转换它,如下所示:
select cast(Datediff(ms, '1970-01-01',GETUTCDATE()) AS bigint)
但它给了我这个错误:
Msg 535,Level 16,State 0,Line 2 日期函数导致溢出。分隔两个日期/时间实例的日期部分数量太大。尝试使用具有不太精确的日期部分的datediff。
我不想这样做:
select cast(Datediff(minute, '1970-01-01',GETUTCDATE()) AS bigint)*60*1000
因为它不会给我准确的结果。有人可以帮帮我吗?
答案 0 :(得分:5)
对于仍在寻找此项目的人,您可以使用DATEDIFF_BIG功能。这在SQL 2016 +,Azure
中受支持https://docs.microsoft.com/en-us/sql/t-sql/functions/datediff-big-transact-sql
答案 1 :(得分:4)
你确定需要它到毫秒(千分之一秒)吗?
请注意,1天= 86,400,000ms(是的,8640万)
1年=约316亿毫秒。
1970年(截至今天)44年前,大约是1.4万亿毫秒之前。
当然,bigint可以处理它,不幸的是你也达到DATEDIFF
的限制,这是文档中的引用:
如果返回值超出int(-2,147,483,648到+2,147,483,647)的范围,则返回错误。对于毫秒,startdate和enddate之间的最大差异是24天,20小时,31分钟和23.647秒。第二,最大差异是68年。
所以,你可以安全地获得一段时间内的差异(只要你不会走得太远),然后你可以从今天开始计算毫秒数,例如:
SELECT
CAST(DATEDIFF(second, '1970-01-01', CAST(GetUtcDate() AS date)) AS bigint)
AS [SecondsToStartOfDay],
DATEDIFF(ms, CAST(GetUtcDate() AS date), GetUtcDate())
AS [MillisecondsSinceStartOfDay],
(CAST(DATEDIFF(second, '1970-01-01', CAST(GetUtcDate() AS date)) AS bigint)*1000)
+ DATEDIFF(ms, CAST(GetUtcDate() AS date), GetUtcDate())
AS [Milliseconds]
前两列只是为了显示所涉及的步骤。
答案 2 :(得分:2)
使用此查询可以获得自1970年以来的DateTime到毫秒
SELECT CAST(Datediff(s, '1970-01-01', GETUTCDATE()) AS BIGINT)*1000
答案 3 :(得分:1)
这是一个Microsoft SQL函数,它以毫秒为单位返回UTC时间(自1970年以来的毫秒数),其结果等于Java.currentTimeMillis()
CREATE FUNCTION dbo.currentTimeMilliseconds()
RETURNS BIGINT
WITH EXECUTE AS CALLER
AS
BEGIN
DECLARE @t datetime = CONVERT (datetime, GETUTCDATE());
DECLARE @days BIGINT = Datediff(day, '1970-01-01',@t);
DECLARE @t_hours BIGINT = DATEPART(HOUR, @t);
DECLARE @t_minuts BIGINT = DATEPART(MINUTE, @t);
DECLARE @t_seconds BIGINT = DATEPART(SECOND, @t);
DECLARE @t_miliseconds BIGINT = DATEPART(MILLISECOND, @t);
RETURN @days * 1000 * 60 * 60 * 24 + @t_hours * 60 *60 *1000 + @t_minuts * 60 * 1000 + @t_seconds * 1000 + @t_miliseconds;
END
GO
答案 4 :(得分:0)
选择Datediff_big(MS,' 1970-01-01',GETUTCDATE())
我确认了结果。
在匿名评论中找到mitchfincher.blogspot.com/2013/09/convert-sql-server-datetime-to.html。
答案 5 :(得分:0)
这里有一些SQL代码可以完成这项工作。
假定数据库服务器的本地时间是中欧(夏/冬)时间(CET / CEST)。
(取决于您将UTC还是本地时间保存到datetime列中)
注意-夏时制:
从冬季更改为夏季(3月底)
在三月的最后一个星期日早晨,时钟从02:00到03:00进行。
“一个人损失一个小时。”
从夏季更改为冬季(10月底)
在十月的最后一个星期日早晨,时钟从03:00推迟到02:00。
“一个人赢得一个小时。”
PRINT 'Begin Executing "01_fu_dtLastSundayInMonth.sql"'
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fu_dtLastSundayInMonth]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fu_dtLastSundayInMonth]() RETURNS int BEGIN RETURN 0 END ')
END
GO
/*
SET DATEFIRST 3; -- Monday
WITH CTE AS (
SELECT 1 AS i, CAST('20190101' AS datetime) AS mydate
UNION ALL
SELECT i+1 AS i, DATEADD(month, 1, CTE.mydate) AS mydate
FROM CTE WHERE i < 100
)
SELECT -666 AS i, dbo.fu_dtLastSundayInMonth('17530101') AS lastSundayInMonth, dbo.fu_dtLastSundayInMonth('17530101') AS Control
UNION ALL
SELECT -666 AS i, dbo.fu_dtLastSundayInMonth('99991231') AS lastSundayInMonth, dbo.fu_dtLastSundayInMonth('99991231') AS Control
UNION ALL
SELECT
mydate
,dbo.fu_dtLastSundayInMonth(mydate) AS lastSundayInMonth
,dbo.fu_dtLastSundayInMonth(mydate) AS lastSundayInMonth
,CAST(NULL AS datetime) AS Control
--,DATEADD(day,DATEDIFF(day,'19000107', DATEADD(MONTH, DATEDIFF(MONTH, 0, mydate, 30))/7*7,'19000107') AS Control
FROM CTE
*/
-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Return Datum von letztem Sonntag im Monat
-- mit gleichem Jahr und Monat wie @in_DateTime
-- =====================================================================
ALTER FUNCTION [dbo].[fu_dtLastSundayInMonth](@in_DateTime datetime )
RETURNS DateTime
AS
BEGIN
-- Abrunden des Eingabedatums auf 00:00:00 Uhr
DECLARE @dtReturnValue AS DateTime
-- 26.12.9999 SO
IF @in_DateTime >= CAST('99991201' AS datetime)
RETURN CAST('99991226' AS datetime);
-- @dtReturnValue is now last day of month
SET @dtReturnValue = DATEADD
(
DAY
,-1
,DATEADD
(
MONTH
,1
,CAST(CAST(YEAR(@in_DateTime) AS varchar(4)) + RIGHT('00' + CAST(MONTH(@in_DateTime) AS varchar(2)), 2) + '01' AS datetime)
)
)
;
-- SET DATEFIRST 1 -- Monday - Super easy !
-- SET DATEFIRST != 1 - PHUK THIS !
SET @dtReturnValue = DATEADD
(
day
,
-
(
(
-- DATEPART(WEEKDAY, @lastDayofMonth) -- with SET DATEFIRST 1
DATEPART(WEEKDAY, @dtReturnValue) + @@DATEFIRST - 2 % 7 + 1
)
%7
)
, @dtReturnValue
);
RETURN @dtReturnValue;
END
GO
GO
PRINT 'Done Executing "01_fu_dtLastSundayInMonth.sql"'
GO
PRINT 'Begin Executing "02_fu_dtIsCEST.sql"'
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fu_dtIsCEST]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fu_dtIsCEST]() RETURNS int BEGIN RETURN 0 END ')
END
GO
-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fu_dtIsCEST('2019-03-31T01:00:00'), dbo.fu_dtIsCEST('2019-03-31T04:00:00')
ALTER FUNCTION [dbo].[fu_dtIsCEST](@in_DateTime datetime )
RETURNS bit
AS
BEGIN
DECLARE @dtReturnValue AS bit
-- https://www.linker.ch/eigenlink/sommerzeit_winterzeit.htm
-- Umstellung von Winterzeit auf Sommerzeit (Ende März):
-- Am letzten Sonntagmorgen im März werden die Uhren von 02:00 auf 03:00 Uhr vorgestellt.
-- Man verliert eine Stunde.
-- Umstellung von Sommerzeit auf Winterzeit (Ende Oktober):
-- Am letzten Sonntagmorgen im Oktober werden die Uhren von 03:00 auf 02:00 Uhr zurückgestellt.
-- Man gewinnt eine Stunde.
DECLARE @beginSummerTime datetime
SET @beginSummerTime = dbo.fu_dtLastSundayInMonth(DATEADD(MONTH, 2, DATEADD(YEAR, YEAR(@in_DateTime)-1900, 0)) )
SET @beginSummerTime = DATEADD(HOUR, 2, @beginSummerTime)
DECLARE @beginWinterTime datetime
SET @beginWinterTime = dbo.fu_dtLastSundayInMonth(DATEADD(MONTH, 9, DATEADD(YEAR, YEAR(@in_DateTime)-1900, 0)) )
SET @beginWinterTime = DATEADD(HOUR, 2, @beginWinterTime)
SET @dtReturnValue = 0;
IF @in_DateTime >= @beginSummerTime AND @in_DateTime < @beginWinterTime
BEGIN
SET @dtReturnValue = 1;
END
RETURN @dtReturnValue;
END
GO
GO
PRINT 'Done Executing "02_fu_dtIsCEST.sql"'
GO
PRINT 'Begin Executing "03_fu_dtToEcmaTimeStamp.sql"'
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fu_dtToEcmaTimeStamp]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fu_dtToEcmaTimeStamp]() RETURNS int BEGIN RETURN 0 END ')
END
GO
-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fu_dtToEcmaTimeStamp('2019-03-31T01:00:00', 1), dbo.fu_dtToEcmaTimeStamp('2019-03-31T04:00:00', 1)
ALTER FUNCTION [dbo].[fu_dtToEcmaTimeStamp](@in_DateTime datetime, @in_convert_to_utc bit)
RETURNS bigint
AS
BEGIN
DECLARE @dtReturnValue AS bigint
IF @in_convert_to_utc = 1
BEGIN
SET @in_DateTime =
CASE WHEN dbo.fu_dtIsCEST(@in_DateTime) = 1
THEN DATEADD(HOUR, -2, @in_DateTime)
ELSE DATEADD(HOUR, -1, @in_DateTime)
END;
END
SET @dtReturnValue =
CAST
(
DATEDIFF
(
HOUR
,CAST('19700101' AS datetime)
,@in_DateTime
)
AS bigint
) *60*60*1000
+
DATEDIFF
(
MILLISECOND
,CAST(FLOOR(CAST(@in_DateTime AS float)) AS datetime)
,@in_DateTime
) % (60*60*1000)
;
RETURN @dtReturnValue;
END
GO
GO
PRINT 'Done Executing "03_fu_dtToEcmaTimeStamp.sql"'
GO
PRINT 'Begin Executing "04_fu_dtFromEcmaTimeStamp.sql"'
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fu_dtFromEcmaTimeStamp]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
EXECUTE(N'CREATE FUNCTION [dbo].[fu_dtFromEcmaTimeStamp]() RETURNS int BEGIN RETURN 0 END ')
END
GO
-- =====================================================================
-- Author: Stefan Steiger
-- Create date: 01.03.2019
-- Last modified: 01.03.2019
-- Description: Ist @in_DateTime Mitteleuropäische Sommerzeit ?
-- =====================================================================
-- SELECT dbo.fu_dtFromEcmaTimeStamp('1551437088122', 1), dbo.fu_dtFromEcmaTimeStamp('1554069600000', 1)
ALTER FUNCTION [dbo].[fu_dtFromEcmaTimeStamp](@in_timestamp bigint, @in_convert_to_localtime bit)
RETURNS datetime
AS
BEGIN
DECLARE @dtReturnValue AS datetime
DECLARE @hours int
SET @hours = @in_timestamp /(1000*60*60);
DECLARE @milliseconds int
SET @milliseconds = @in_timestamp - (@in_timestamp /(1000*60*60))*(1000*60*60);
SET @dtReturnValue = DATEADD
(
MILLISECOND, @milliseconds,
DATEADD(hour, @hours, CAST('19700101' AS datetime))
)
IF @in_convert_to_localtime = 1
BEGIN
SET @dtReturnValue = DATEADD(HOUR, 1, @dtReturnValue)
SET @dtReturnValue =
CASE WHEN dbo.fu_dtIsCEST(@dtReturnValue) = 1
THEN DATEADD(HOUR, 1, @dtReturnValue)
ELSE @dtReturnValue
END;
END
RETURN @dtReturnValue;
END
GO
GO
PRINT 'Done Executing "04_fu_dtFromEcmaTimeStamp.sql"'
GO