2011-05-03 95 views
4

datediff(ss, '01/01/1970', '12/31/2050')的結果是bigint因此datediff溢出。如何在日期時間支持bigint

如何獲得bigint值到相應的日期,如果最大日期可以在SQL中是int

我需要能夠在SQL(我做一個char01/01/197012/31/2050之間存儲的秒數但該值轉換爲它的日曆日期顯示在網頁中。

任何想法,將不勝感激。

謝謝!

+0

所有Linux/Unix系統中有這個問題爲好。衆所周知,如果沒有從32位更改[時代將溢出](http://en.wikipedia.org/wiki/Unix_time#Representing_the_number)。 – Oded 2011-05-03 19:57:37

回答

2

您可以將日期時間轉換爲浮點數,表示自1900-01-01 00:00:00以來的天數。小於幾天的部分就是分數。將這些數字進行抽象並在一天內按秒縮放應該可以。

DECLARE @ D1 DATETIME

DECLARE @ D2 DATETIME

SELECT @ D1 = '01/01/1970'

SELECT @ D2 = '12 /二千零五十零分之三十一'

SELECT(CAST(@ d2 AS FLOAT) - CAST(@ d1 AS FLOAT))* 3600 * 24

但是,您可能會找到更好的解決方案;)

+0

小數可能會更快我想知道? – Rbjz 2013-04-27 15:04:52

2
CREATE FUNCTION dbo.SecondsSince1970(@date datetime) 
RETURNS bigint 
AS 
BEGIN 
    RETURN 
     CASE WHEN @date > '2038-01-19' 
      THEN CAST(DATEDIFF(ss, '2038-01-19', @date) AS bigint) 
       + DATEDIFF(ss, '1970-01-01', '2038-01-19') 
      ELSE DATEDIFF(ss, '1970-01-01', @date) 
     END 
END 
4

這會給你毫秒。容易適應秒......

declare @dfrom datetime = '1970-01-01 16:15:33.021' 
declare @dto datetime = '2058-01-01 15:00:55.557' 

declare @diff bigint = 
    cast(DATEDIFF(d, @dfrom, @dto) as bigint) * 24 * 3600 * 1000 
    + DATEDIFF(ms, cast(@dfrom as time), cast(@dto as time))  

declare @dreverse datetime = 
    dateadd(ms, @diff % (1000 * 3600 * 24), 
     dateadd(day, @diff/(1000 * 3600 * 24), @dfrom)) 

select @dfrom as [From], @dto as [To], @diff as [Diff], @dreverse as [Reverse] for xml path('') 

給出:

<From>1970-01-01T16:15:33.020</From> 
<To>2058-01-01T15:00:55.557</To> 
<Diff>2777064322537</Diff> 
<Reverse>2058-01-01T15:00:55.557</Reverse> 
+1

這不是一個好主意,除非你很樂意忽略第一天和最後一天的時間和秒數。 Datediff計算「界限」。如果您選擇了datediff(d,'2013-01-01 04:00:00','2013-01-02 10:00:00'),則結果爲1(日),而不是1.25天,因爲返回類型是整數。 – Davos 2014-04-04 05:45:30

+1

達沃斯,這正是爲什麼在第二行有ms部分...? – Rbjz 2014-04-20 17:43:40

+0

嗯,我錯過了,但仍然有一個問題,如果你投了時間之後,你的時間可能會在你的TO時間的一天晚些時候,所以你會增加負的毫秒。也許從一整天的毫秒減去,如果它是負的 – Davos 2014-04-28 07:59:08

相關問題