我需要在SQL Server 2008中创建一个模仿mysql UNIX_TIMESTAMP()
的函数。
提前致谢!
答案 0 :(得分:25)
如果您对1970年以前的日期或毫秒级精度不感到困扰,请执行以下操作:
-- SQL Server
SELECT DATEDIFF(s, '1970-01-01 00:00:00', DateField)
几乎和MySQL的内置函数一样简单:
-- MySQL
SELECT UNIX_TIMESTAMP(DateField);
其他语言(Oracle,PostgreSQL等):How To Get The Current Epoch Time (Unix Timestamp)
答案 1 :(得分:17)
试试这篇文章: http://skinn3r.wordpress.com/2009/01/26/t-sql-datetime-to-unix-timestamp/
CREATE FUNCTION UNIX_TIMESTAMP (
@ctimestamp datetime
)
RETURNS integer
AS
BEGIN
/* Function body */
declare @return integer
SELECT @return = DATEDIFF(SECOND,{d '1970-01-01'}, @ctimestamp)
return @return
END
或这篇文章:
代码如下:
CREATE FUNCTION dbo.DTtoUnixTS
(
@dt DATETIME
)
RETURNS BIGINT
AS
BEGIN
DECLARE @diff BIGINT
IF @dt >= '20380119'
BEGIN
SET @diff = CONVERT(BIGINT, DATEDIFF(S, '19700101', '20380119'))
+ CONVERT(BIGINT, DATEDIFF(S, '20380119', @dt))
END
ELSE
SET @diff = DATEDIFF(S, '19700101', @dt)
RETURN @diff
END
样本用法:
SELECT dbo.DTtoUnixTS(GETDATE())
-- or
SELECT UnixTimestamp = dbo.DTtoUnixTS(someColumn)
FROM someTable
答案 2 :(得分:2)
我经常需要一个毫秒精度的unix时间戳。以下内容将为您提供当前的unixtime FLOAT
;将上面的答案换行以获取函数或转换任意字符串。
SQL Server上的DATETIME
数据类型只有3毫秒,所以我有不同的SQL Server 2005和2008+示例。遗憾的是,没有DATEDIFF2
函数,因此即使使用2008+,也需要各种技巧来避免DATEDIFF
整数溢出。 (我无法相信他们引入了一个全新的DATETIME2
数据类型而没有修复它。)
对于常规的旧DATETIME
,我只是使用一个低级的强制转换来浮动,它返回(浮动点)自1900年以来的天数。
现在我知道了,你在想什么关于LEAP SECONDS?!?!无论是Windows时间还是unixtime都没有真正相信闰秒:SQL Server的一天总是1.00000天,unixtime的时间是86400秒。 This wikipedia article讨论了unixtime在闰秒期间的行为方式; Windows我相信只是像任何其他时钟错误一样查看闰秒。因此,当闰秒发生时,两个系统之间没有系统漂移,但在闰秒期间和紧接着闰秒后,它们不会在亚秒级别上达成一致。
-- the right way, for sql server 2008 and greater
declare @unixepoch2 datetime2;
declare @now2 Datetime2;
declare @days int;
declare @millisec int;
declare @today datetime2;
set @unixepoch2 = '1970-01-01 00:00:00.0000';
set @now2 = SYSUTCDATETIME();
set @days = DATEDIFF(DAY,@unixepoch2,@now2);
set @today = DATEADD(DAY,@days,@unixepoch2);
set @millisec = DATEDIFF(MILLISECOND,@today,@now2);
select (CAST (@days as float) * 86400) + (CAST(@millisec as float ) / 1000)
as UnixTimeFloatSQL2008
-- Note datetimes are only accurate to 3 msec, so this is less precise
-- than above, but works on any edition of SQL Server.
declare @sqlepoch datetime;
declare @unixepoch datetime;
declare @offset float;
set @sqlepoch = '1900-01-01 00:00:00';
set @unixepoch = '1970-01-01 00:00:00';
set @offset = cast (@sqlepoch as float) - cast (@unixepoch as float);
select ( cast (GetUTCDate() as float) + @offset) * 86400
as UnixTimeFloatSQL2005;
-- Future developers may hate you, but you can put the offset in
-- as a const because it isn't going to change.
declare @sql_to_unix_epoch_in_days float;
set @sql_to_unix_epoch_in_days = 25567.0;
select ( cast (GetUTCDate() as float) - @sql_to_unix_epoch_in_days) * 86400.0
as UnixTimeFloatSQL2005MagicNumber;
FLOAT实际上默认为SQL Server上的8字节双精度数,因此对于许多用例而言优于32位INT
。 (例如,他们在2038年不会翻身。)
答案 3 :(得分:0)
Necromancing。
ODBC方式:
DECLARE @unix_timestamp varchar(20)
-- SET @unix_timestamp = CAST({fn timestampdiff(SQL_TSI_SECOND,{d '1970-01-01'}, CURRENT_TIMESTAMP)} AS varchar(20))
IF CURRENT_TIMESTAMP >= '20380119'
BEGIN
SET @unix_timestamp = CAST
(
CAST
(
{fn timestampdiff(SQL_TSI_SECOND,{d '1970-01-01'}, {d '2038-01-19'})}
AS bigint
)
+
CAST
(
{fn timestampdiff(SQL_TSI_SECOND,{d '2038-01-19'}, CURRENT_TIMESTAMP)}
AS bigint
)
AS varchar(20)
)
END
ELSE
SET @unix_timestamp = CAST({fn timestampdiff(SQL_TSI_SECOND,{d '1970-01-01'}, CURRENT_TIMESTAMP)} AS varchar(20))
PRINT @unix_timestamp
答案 4 :(得分:0)
当调用标量值函数时,可以使用以下语法
功能脚本:
USE [Database]
GO
/****** Object: UserDefinedFunction [dbo].[UNIX_TIMESTAMP] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[UNIX_TIMESTAMP] (
@ctimestamp datetime
)
RETURNS integer
AS
BEGIN
/* Function body */
declare @return integer
SELECT @return = DATEDIFF(SECOND,{d '1970-01-01'}, @ctimestamp)
return @return
END
GO
通话功能:
SELECT dbo.UNIX_TIMESTAMP(GETDATE());
答案 5 :(得分:0)
Sql Server 2016和更高版本具有DATEDIFF_BIG函数,可用于获取毫秒。
SELECT DATEDIFF_BIG(millisecond, '1970-01-01 00:00:00', GETUTCDATE())
创建函数
CREATE FUNCTION UNIX_TIMESTAMP()
RETURNS BIGINT
AS
BEGIN
RETURN DATEDIFF_BIG(millisecond, '1970-01-01 00:00:00', GETUTCDATE())
END
并执行它
SELECT dbo.UNIX_TIMESTAMP()
答案 6 :(得分:0)
这是不声明任何函数或变量的单行解决方案:
SELECT CAST(CAST(GETUTCDATE()-'1970-01-01' AS decimal(38,10))*86400000.5 as bigint)
答案 7 :(得分:0)
对于毫秒结果的时间戳,我从这里https://gist.github.com/rsim/d11652a8336137832df9找到了这个解决方案:
SELECT (cast(DATEDIFF(s, '1970-01-01', GETUTCDATE()) as bigint)*1000+datepart(ms,getutcdate()))
@Rafe的答案对我没有正确起作用(MSSQL 20212)-我有9秒的时间差。
答案 8 :(得分:0)
如果您必须处理以前版本的 SQL Server (<2016) 并且您只关心正时间戳,我将在这里发布我为非常远的日期找到的解决方案(这样您就可以摆脱@rkosegi 的回答中的 IF .
我所做的是首先计算天数的差异,然后加上剩余的秒数差异。
CREATE FUNCTION [dbo].[UNIX_TIMESTAMP]
(
@inputDate DATETIME
)
RETURNS BIGINT
AS
BEGIN
DECLARE @differenceInDays BIGINT, @result BIGINT;
SET @differenceInDays = DATEDIFF(DAY, '19700101', @inputDate)
IF @differenceInDays >= 0
SET @result = (@differenceInDays * 86400) + DATEDIFF(SECOND, DATEADD(DAY, 0, DATEDIFF(DAY, 0, @inputDate)), @inputDate)
ELSE
SET @result = 0
RETURN @result
END