2012-06-25 81 views
0

這個問題的問題here如何計算在T-SQL年齡年,月,日,時,分,秒和毫秒

我試圖擴大丹麥人的回答的延伸,但結果是有點問題。

DECLARE @dateFrom DATETIME 
DECLARE @dateTo DATETIME 
DECLARE @tmpdate DATETIME 
DECLARE @years INT 
DECLARE @months INT 
DECLARE @days INT 
DECLARE @hours INT 
DECLARE @minutes INT 
DECLARE @seconds INT 
DECLARE @milliseconds INT 

SELECT @dateFrom = '2011-01-01 11:24:38:100' 
SELECT @dateTo = '2012-01-01 11:24:38:110' 

SELECT @tmpdate = @dateFrom 

SELECT @years = DATEDIFF(yy, @tmpdate, @dateTo) 
     - CASE WHEN (MONTH(@dateFrom) > MONTH(@dateTo)) OR (MONTH(@dateFrom) = MONTH(@dateTo) AND DAY(@dateFrom) > DAY(@dateTo)) 
      THEN 1 
      ELSE 0 
     END 
SELECT @tmpdate   = DATEADD(yy, @years, @tmpdate) 
SELECT @months   = DATEDIFF(mm, @tmpdate, @dateTo) - CASE WHEN DAY(@dateFrom) > DAY(@dateTo) THEN 1 ELSE 0 END 
SELECT @tmpdate   = DATEADD(mm, @months, @tmpdate) 
SELECT @days   = DATEDIFF(dd, @tmpdate, @dateTo) 
SELECT @tmpdate   = DATEADD(dd, @days, @tmpdate) 
SELECT @hours   = DATEDIFF(hh, @tmpdate, @dateTo) 
SELECT @tmpdate   = DATEADD(hh, @hours, @tmpdate) 
SELECT @minutes   = DATEDIFF(mi, @tmpdate, @dateTo) 
SELECT @tmpdate   = DATEADD(mi, @minutes, @tmpdate) 
SELECT @seconds   = DATEDIFF(ss, @tmpdate, @dateTo) 
SELECT @tmpdate   = DATEADD(ss, @seconds, @tmpdate) 
SELECT @milliseconds = DATEDIFF(ms, @tmpdate, @dateTo) 

SELECT 
    @years AS [years] 
    , @months AS [months] 
    , @days AS [days] 
    , @hours AS [hours] 
    , @minutes AS [minutes] 
    , @seconds AS [seconds] 
    , @milliseconds AS [milliseconds] 

,其結果是:

years months days hours minutes seconds milliseconds 
1  0  0  0  0  0  10 

但是當我運行:

SELECT @dateFrom = '2011-01-02 11:24:38:110' 
SELECT @dateTo = '2012-01-01 10:23:37:100' 

結果是:

years months days hours minutes seconds milliseconds 
0  11  30  -1  -1  -1  -10 

幫助將不勝感激!

回答

2

答案是正確的,但它的負面values.You顯示需要使用ABS返回正值

SELECT 
@years AS [years] 
, abs(@months) AS [months] 
, abs(@days) AS [days] 
, abs(@hours) AS [hours] 
, abs(@minutes) AS [minutes] 
, abs(@seconds) AS [seconds] 
, abs(@milliseconds) AS [milliseconds] 
+0

您提供的代碼不能處理所有正確的案例。例如,試一下,dateFrom:'2014-04-24 13:59:00'dateTo:'2014-04-24 14:01:00' –

2

你得到這些負值,因爲在@dateFrom的日期早於晚於@dateTo日期,我覺得你可以做的是啓動時發生這種情況的過程之前交換這些值是最好的,這樣你就不會需要的過程之後重新格式化您的變量:

DECLARE @auxDate DATETIME 

IF (@dateFrom>@dateTo) 
BEGIN 
    SET @auxDate = @dateFrom 
    SET @dateFrom = @dateTo 
    SET @dateTo = @auxDate 
END 

    -- Your code.. 
0
DECLARE @dateFrom DATETIME 
DECLARE @dateTo DATETIME 
DECLARE @tmpdate DATETIME 
DECLARE @years INT 
DECLARE @months INT 
DECLARE @days INT 
DECLARE @hours INT 
DECLARE @minutes INT 
DECLARE @seconds INT 
DECLARE @milliseconds INT 
DECLARE @sign CHAR 

--SELECT @dateFrom = '2011-01-01 11:24:38:100' 
--SELECT @dateTo = '2012-01-01 11:24:38:110' 

SELECT @dateFrom = '2012-02-03 11:24:38:000' 
SELECT @dateTo  = '2013-03-04 12:25:39:003' 
SELECT @sign  = '+' 

IF @dateFrom > @dateTo 
BEGIN 
    SET @tmpdate = @dateFrom 
    SET @dateFrom = @dateTo 
    SET @dateTo = @tmpdate 
    SET @sign = '-' 
END 

SELECT @tmpdate = @dateFrom 

SELECT @years   = DATEDIFF(yy, @tmpdate, @dateTo) 
          - CASE WHEN 
            (DATEPART(mm, @dateFrom) > DATEPART(mm, @dateTo)) 
           OR (DATEPART(mm, @dateFrom) = DATEPART(mm, @dateTo) AND DATEPART(dd, @dateFrom) > DATEPART(dd, @dateTo)) 
           OR (DATEPART(dd, @dateFrom) = DATEPART(dd, @dateTo) AND DATEPART(hh, @dateFrom) > DATEPART(hh, @dateTo)) 
           OR (DATEPART(hh, @dateFrom) = DATEPART(hh, @dateTo) AND DATEPART(mi, @dateFrom) > DATEPART(mi, @dateTo)) 
           OR (DATEPART(mi, @dateFrom) = DATEPART(mi, @dateTo) AND DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo)) 
           OR (DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo) AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo)) 
           THEN 1 
           ELSE 0 
          END 
SELECT @tmpdate   = DATEADD(yy, @years, @tmpdate) 
SELECT @months   = DATEDIFF(mm, @tmpdate, @dateTo) 
          - CASE WHEN 
            (DATEPART(dd, @dateFrom) > DATEPART(dd, @dateTo)) 
           OR (DATEPART(dd, @dateFrom) = DATEPART(dd, @dateTo) AND DATEPART(hh, @dateFrom) > DATEPART(hh, @dateTo)) 
           OR (DATEPART(hh, @dateFrom) = DATEPART(hh, @dateTo) AND DATEPART(mi, @dateFrom) > DATEPART(mi, @dateTo)) 
           OR (DATEPART(mi, @dateFrom) = DATEPART(mi, @dateTo) AND DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo)) 
           OR (DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo) AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo)) 
           THEN 1 
           ELSE 0 
          END 
SELECT @tmpdate   = DATEADD(mm, @months, @tmpdate) 
SELECT @days   = DATEDIFF(dd, @tmpdate, @dateTo) 
          - CASE WHEN 
            (DATEPART(hh, @dateFrom) > DATEPART(hh, @dateTo)) 
           OR (DATEPART(hh, @dateFrom) = DATEPART(hh, @dateTo) AND DATEPART(mi, @dateFrom) > DATEPART(mi, @dateTo)) 
           OR (DATEPART(mi, @dateFrom) = DATEPART(mi, @dateTo) AND DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo)) 
           OR (DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo) AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo)) 
           THEN 1 
           ELSE 0 
          END 
SELECT @tmpdate   = DATEADD(dd, @days, @tmpdate) 
SELECT @hours   = DATEDIFF(hh, @tmpdate, @dateTo) 
          - CASE WHEN 
            (DATEPART(mi, @dateFrom) > DATEPART(mi, @dateTo)) 
           OR (DATEPART(mi, @dateFrom) = DATEPART(mi, @dateTo) AND DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo)) 
           OR (DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo) AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo)) 
           THEN 1 
           ELSE 0 
          END 
SELECT @tmpdate   = DATEADD(hh, @hours, @tmpdate) 
SELECT @minutes   = DATEDIFF(mi, @tmpdate, @dateTo) 
          - CASE WHEN 
            (DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo)) 
           OR (DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo) AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo)) 
           THEN 1 
           ELSE 0 
          END 
SELECT @tmpdate   = DATEADD(mi, @minutes, @tmpdate) 
SELECT @seconds   = DATEDIFF(ss, @tmpdate, @dateTo) 
          - CASE WHEN 
            (DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo)) 
           THEN 1 
           ELSE 0 
          END 
SELECT @tmpdate   = DATEADD(ss, @seconds, @tmpdate) 
SELECT @milliseconds = DATEDIFF(ms, @tmpdate, @dateTo) 

SELECT 
    @sign AS [sign] 
    , @years AS [years] 
    , @months AS [months] 
    , @days AS [days] 
    , @hours AS [hours] 
    , @minutes AS [minutes] 
    , @seconds AS [seconds] 
    , @milliseconds AS [milliseconds] 
0

PL輕鬆看看我的問題,這是回答Here
它與像的情況下交易:

@dateFrom = '2014年4月24日十三時59分零零秒'
@dateTo = '2014年4月24日14:01:00'

你代碼爲這些值返回錯誤的日期。

相關問題