Sự khác biệt của hai ngày giờ trong máy chủ sql


83

Có cách nào để lấy sự khác biệt giữa hai datetimetrong máy chủ sql?

Ví dụ, ngày của tôi là

  1. 2010-01-22 15:29:55.090
  2. 2010-01-22 15:30:09.153

Vì vậy, kết quả nên được 14.063 seconds.


2
Bạn nhận được tất cả các datediffcâu trả lời nhưng dường như không có câu trả lời nào nhắc nhở bạn rằng bạn có thể nhận được kết quả tiêu cực từ nó tùy thuộc vào thứ tự tham số.
Pasi Savolainen

Câu trả lời:


94

Chỉ cần lưu ý thêm về DateDiff, nó tính số lần bạn vượt qua ranh giới mà bạn chỉ định làm đơn vị của mình, vì vậy sẽ có vấn đề nếu bạn đang tìm kiếm khoảng thời gian chính xác. ví dụ

select datediff (m, '20100131', '20100201')

đưa ra câu trả lời là 1, bởi vì nó vượt qua ranh giới từ tháng 1 đến tháng 2, vì vậy mặc dù khoảng thời gian là 2 ngày, dateiff sẽ trả về giá trị 1 - nó vượt qua 1 ranh giới ngày.

select datediff(mi, '2010-01-22 15:29:55.090' , '2010-01-22 15:30:09.153')

Cung cấp giá trị 1, một lần nữa, nó đã vượt qua ranh giới phút một lần, vì vậy, mặc dù khoảng 14 giây, nó sẽ được trả về dưới dạng một phút khi sử dụng Minutes làm đơn vị.



18
SELECT  DATEDIFF(day, '2010-01-22 15:29:55.090', '2010-01-22 15:30:09.153')

Thay thế daybằng các đơn vị khác mà bạn muốn để có được sự khác biệt, như second, minutev.v.


16

Tôi có thể đề cập đến bốn chức năng quan trọng của MS SQL Server có thể rất hữu ích:

1) Hàm DATEDIFF () chịu trách nhiệm tính toán sự khác biệt giữa hai ngày, kết quả có thể là " năm quý tháng ngày năm năm ngày tuần giờ phút giây mili giây micro giây nano giây ", được chỉ định trên tham số đầu tiên ( datepart ):

select datediff(day,'1997-10-07','2011-09-11')

2) Bạn có thể sử dụng hàm GETDATE () để lấy thời gian thực và tính toán chênh lệch của một số ngày và ngày thực tế:

select datediff(day,'1997-10-07', getdate() )

3) Một hàm quan trọng khác là DATEADD () , được sử dụng để chuyển đổi một số giá trị trong datetime bằng cách sử dụng cùng một phần ngày của dateiff , mà bạn có thể thêm (với giá trị dương) hoặc giá trị con (với giá trị âm) vào một ngày cơ sở:

select DATEADD(day,  45, getdate()) -- actual datetime adding 45 days
select DATEADD(  s,-638, getdate()) -- actual datetime subtracting 10 minutes and 38 seconds

4) Hàm CONVERT () được tạo ra để định dạng ngày tháng như bạn cần, nó không phải là hàm tham số, nhưng bạn có thể sử dụng một phần của kết quả để định dạng kết quả như bạn cần:

select convert(  char(8), getdate() ,   8) -- part hh:mm:ss of actual datetime
select convert(  varchar, getdate() , 112) -- yyyymmdd
select convert( char(10), getdate() ,  20) -- yyyy-mm-dd limited by 10 characters

DATETIME lạnh được tính bằng giây và một kết quả thú vị khi kết hợp bốn chức năng này là hiển thị sự khác biệt định dạng um giờ, phút và giây ( hh: mm: ss ) giữa hai ngày:

declare  @date1 datetime, @date2 datetime
set @date1=DATEADD(s,-638,getdate())
set @date2=GETDATE()

select convert(char(8),dateadd(s,datediff(s,@date1,@date2),'1900-1-1'),8)

... kết quả là 00:10:38 (638 giây = 600 giây + 38 giây = 10 phút 38 giây)

Một vi dụ khac:

select distinct convert(char(8),dateadd(s,datediff(s, CRDATE , GETDATE() ),'1900-1-1'),8) from sysobjects order by 1

9

Tôi đã thử cách này và nó hoạt động. Tôi đã sử dụng phiên bản SQL Server 2016

SELECT DATEDIFF(MILLISECOND,'2010-01-22 15:29:55.090', '2010-01-22 15:30:09.153')/1000.00;

Các hàm DATEDIFF khác nhau là:

SELECT DATEDIFF(year,        '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(quarter,     '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(month,       '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(dayofyear,   '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(day,         '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(week,        '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(hour,        '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(minute,      '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(second,      '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(millisecond, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');

Tham khảo: https://docs.microsoft.com/en-us/sql/t-sql/functions/datediff-transact-sql?view=sql-server-2017


7

Ok, tất cả chúng ta đều biết câu trả lời liên quan đến DATEDIFF(). Nhưng điều đó chỉ mang lại cho bạn một nửa kết quả mà bạn có thể đạt được. Điều gì sẽ xảy ra nếu bạn muốn nhận kết quả ở định dạng con người có thể đọc được, về Phút và Giây giữa hai DATETIMEgiá trị?

Các CONVERT(), DATEADD()và tất nhiên DATEDIFF()chức năng này là hoàn hảo cho một kết quả dễ dàng dễ đọc hơn mà khách hàng của bạn có thể sử dụng, thay vì một số.

I E

CONVERT(varchar(5), DATEADD(minute, DATEDIFF(MINUTE, date1, date2), 0), 114) 

Điều này sẽ cung cấp cho bạn một cái gì đó như:

HH: MM

Nếu bạn muốn chính xác hơn, chỉ cần tăng VARCHAR().

CONVERT(varchar(12), DATEADD(minute, DATEDIFF(MINUTE, date1, date2), 0), 114) 

HH: MM.SS.MS


5

Nội bộ trong SQL Server ngày được lưu trữ dưới dạng 2 số nguyên. Số nguyên đầu tiên là số ngày trước hoặc sau ngày gốc (1900/01/01). Số nguyên thứ hai lưu trữ số tích tắc đồng hồ sau nửa đêm, mỗi tích tắc là 1/300 giây.

Thông tin thêm tại đây

Bởi vì điều này, tôi thường thấy cách đơn giản nhất để so sánh các ngày là chỉ cần trừ chúng đi. Điều này xử lý 90% các trường hợp sử dụng của tôi. Ví dụ,

select date1, date2, date2 - date1 as DifferenceInDays
from MyTable
...

Khi tôi cần câu trả lời trong các đơn vị khác với ngày, tôi sẽ sử dụng DateDiff .


6
Lưu ý rằng điều này chỉ áp dụng đối với người già DATETIMEloại, không DATE, TIMEhoặc DATETIME2. Ngoài ra, giá trị được trả về sẽ là một giá trị khác DATETIME, vì vậy bạn sẽ cần truyền nó để có được số ngày có thể đọc được giữa các ngày.

5

Có một số cách để xem xét sự khác biệt về ngày tháng và nhiều cách khác khi so sánh ngày / giờ. Đây là những gì tôi sử dụng để nhận được sự khác biệt giữa hai ngày được định dạng là "HH: MM: SS":

ElapsedTime AS
      RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate)        / 3600 AS VARCHAR(2)), 2) + ':'
    + RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) % 3600 /   60 AS VARCHAR(2)), 2) + ':'
    + RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) %   60        AS VARCHAR(2)), 2)

Tôi đã sử dụng cột này cho một cột được tính toán, nhưng bạn có thể viết lại nó dưới dạng UDF hoặc phép tính truy vấn. Lưu ý rằng logic này làm tròn số giây phân số xuống; 00: 00.00 đến 00: 00.999 được coi là 0 giây và được hiển thị là "00:00:00".

Nếu bạn dự đoán rằng khoảng thời gian có thể dài hơn một vài ngày, mã này sẽ chuyển sang định dạng D: HH: MM: SS khi cần:

ElapsedTime AS
    CASE WHEN DATEDIFF(S, StartDate, EndDate) >= 359999
        THEN
                          CAST(DATEDIFF(S, StartDate, EndDate) / 86400        AS VARCHAR(7)) + ':'
            + RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) % 86400 / 3600 AS VARCHAR(2)), 2) + ':'
            + RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) %  3600 /   60 AS VARCHAR(2)), 2) + ':'
            + RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) %    60        AS VARCHAR(2)), 2)
        ELSE
              RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate)        / 3600 AS VARCHAR(2)), 2) + ':'
            + RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) % 3600 /   60 AS VARCHAR(2)), 2) + ':'
            + RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) %   60        AS VARCHAR(2)), 2)
        END


3
SELECT DATEDIFF(yyyy, '2011/08/25', '2017/08/25') AS DateDiff

Nó cho bạn sự khác biệt giữa hai ngày trong năm

Kết quả là đây (2017-2011) = 6

Cú pháp:

DATEDIFF(interval, date1, date2)

2

Sử dụng cái này cho DD:MM:SS:

SELECT CONVERT(VARCHAR(max), Datediff(dd, '2019-08-14 03:16:51.360', 
         '2019-08-15 05:45:37.610')) 
       + ':' 
       + CONVERT(CHAR(8), Dateadd(s, Datediff(s, '2019-08-14 03:16:51.360', 
         '2019-08-15 05:45:37.610'), '1900-1-1'), 8) 

1

Vì vậy, đây không phải là câu trả lời của tôi nhưng tôi cũng vừa tìm thấy điều này trong khi tìm kiếm trên mạng cho một câu hỏi như thế này. Anh chàng này đã thiết lập một thủ tục để tính giờ, phút và giây. Các liên kết và mã:

--Creating Function
If OBJECT_ID('UFN_HourMinuteSecond') Is Not Null
Drop Function dbo.UFN_HourMinuteSecond
Go
Exec(
'Create Function dbo.UFN_HourMinuteSecond
(
@StartDateTime DateTime,
@EndDateTime DateTime
) Returns Varchar(10) 
As
Begin

Declare @Seconds Int,
@Minute Int,
@Hour Int,
@Elapsed Varchar(10)

Select @Seconds = ABS(DateDiff(SECOND ,@StartDateTime,@EndDateTime))

If @Seconds >= 60 
Begin
select @Minute = @Seconds/60
select @Seconds = @Seconds%60

If @Minute >= 60
begin
select @hour = @Minute/60
select @Minute = @Minute%60
end

Else
Goto Final 
End

Final:
Select @Hour = Isnull(@Hour,0), @Minute = IsNull(@Minute,0), @Seconds =               IsNull(@Seconds,0)
select @Elapsed = Cast(@Hour as Varchar) + '':'' + Cast(@Minute as Varchar) + '':'' +     Cast(@Seconds as Varchar)

Return (@Elapsed)
End'
)

1
declare @dt1 datetime='2012/06/13 08:11:12', @dt2 datetime='2012/06/12 02:11:12'

select CAST((@dt2-@dt1) as time(0))


1
select
datediff(millisecond,'2010-01-22 15:29:55.090','2010-01-22 15:30:09.153') / 1000.0 as Secs

result:
Secs
14.063

Chỉ nghĩ rằng tôi sẽ đề cập đến nó.


1

TẠO CHỨC NĂNG getDateDiffHours (@fdate AS datetime, @ tdate as datetime) RETURNS varchar (50) AS BEGIN DECLARE @cnt int DECLARE @cntDate datetime DECLARE @dayDiff int DECLARE @dayDiffWk int DECLARE @hrsDiff thập phân (18)

DECLARE @markerFDate datetime
DECLARE @markerTDate datetime

DECLARE @fTime int
DECLARE @tTime int 


DECLARE @nfTime varchar(8)
DECLARE @ntTime varchar(8)

DECLARE @nfdate datetime
DECLARE @ntdate datetime

-------------------------------------
--DECLARE @fdate datetime
--DECLARE @tdate datetime

--SET @fdate = '2005-04-18 00:00:00.000'
--SET @tdate = '2005-08-26 15:06:07.030'
-------------------------------------

DECLARE @tempdate datetime

--setting weekends
SET @fdate = dbo.getVDate(@fdate)
SET @tdate = dbo.getVDate(@tdate)
--RETURN @fdate 

SET @fTime = datepart(hh,@fdate)
SET @tTime = datepart(hh,@tdate)
--RETURN @fTime 
if datediff(hour,@fdate, @tdate) <= 9

        RETURN(convert(varchar(50),0) + ' Days ' + convert(varchar(50),datediff(hour,@fdate, @tdate)))  + ' Hours'
else
--setting working hours
SET @nfTime = dbo.getV00(convert(varchar(2),datepart(hh,@fdate))) + ':' +dbo.getV00(convert(varchar(2),datepart(mi,@fdate))) + ':'+  dbo.getV00(convert(varchar(2),datepart(ss,@fdate)))
SET @ntTime = dbo.getV00(convert(varchar(2),datepart(hh,@tdate))) + ':' +dbo.getV00(convert(varchar(2),datepart(mi,@tdate))) + ':'+  dbo.getV00(convert(varchar(2),datepart(ss,@tdate)))

IF @fTime > 17 
begin
    set @nfTime = '17:00:00'
end 
else
begin
    IF @fTime < 8 
        set @nfTime = '08:00:00'
end 

IF @tTime > 17 
begin
    set @ntTime = '17:00:00'
end 
else
begin
    IF @tTime < 8 
        set @ntTime = '08:00:00'
end 



-- used for working out whole days

SET @nfdate = dateadd(day,1,@fdate) 

SET @ntdate = @tdate
SET @nfdate = convert(varchar,datepart(yyyy,@nfdate)) + '-' + convert(varchar,datepart(mm,@nfdate)) + '-' + convert(varchar,datepart(dd,@nfdate))
SET @ntdate = convert(varchar,datepart(yyyy,@ntdate)) + '-' + convert(varchar,datepart(mm,@ntdate)) + '-' + convert(varchar,datepart(dd,@ntdate))
SET @cnt = 0
SET @dayDiff = 0 
SET @cntDate = @nfdate
SET @dayDiffWk = convert(decimal(18,2),@ntdate-@nfdate)

--select @nfdate,@ntdate

WHILE @cnt < @dayDiffWk
BEGIN   
    IF (NOT DATENAME(dw, @cntDate) = 'Saturday') AND (NOT DATENAME(dw, @cntDate) = 'Sunday')
    BEGIN 
        SET @dayDiff = @dayDiff + 1
    END 
    SET @cntDate = dateadd(day,1,@cntDate)
    SET @cnt = @cnt + 1
END 

--SET @dayDiff = convert(decimal(18,2),@ntdate-@nfdate) --datediff(day,@nfdate,@ntdate)
--SELECT @dayDiff

set @fdate = convert(varchar,datepart(yyyy,@fdate)) + '-' + convert(varchar,datepart(mm,@fdate)) + '-' + convert(varchar,datepart(dd,@fdate)) + ' ' + @nfTime
set @tdate = convert(varchar,datepart(yyyy,@tdate)) + '-' + convert(varchar,datepart(mm,@tdate)) + '-' + convert(varchar,datepart(dd,@tdate)) + ' ' + @ntTime

set @markerFDate = convert(varchar,datepart(yyyy,@fdate)) + '-' + convert(varchar,datepart(mm,@fdate)) + '-' + convert(varchar,datepart(dd,@fdate)) + ' ' + '17:00:00'
set @markerTDate = convert(varchar,datepart(yyyy,@tdate)) + '-' + convert(varchar,datepart(mm,@tdate)) + '-' + convert(varchar,datepart(dd,@tdate)) + ' ' + '08:00:00'

--select @fdate,@tdate
--select @markerFDate,@markerTDate

set @hrsDiff = convert(decimal(18,2),datediff(hh,@fdate,@markerFDate))

--select @hrsDiff
set @hrsDiff = @hrsDiff +  convert(int,datediff(hh,@markerTDate,@tdate))

--select @fdate,@tdate  

IF convert(varchar,datepart(yyyy,@fdate)) + '-' + convert(varchar,datepart(mm,@fdate)) + '-' + convert(varchar,datepart(dd,@fdate)) = convert(varchar,datepart(yyyy,@tdate)) + '-' + convert(varchar,datepart(mm,@tdate)) + '-' + convert(varchar,datepart(dd,@tdate))  
BEGIN
    --SET @hrsDiff = @hrsDiff - 9
    Set @hrsdiff = datediff(hour,@fdate,@tdate)
END 

--select FLOOR((@hrsDiff / 9))

IF (@hrsDiff / 9) > 0 
BEGIN
    SET @dayDiff = @dayDiff + FLOOR(@hrsDiff / 9)
    SET @hrsDiff = @hrsDiff - FLOOR(@hrsDiff / 9)*9
END 

--select convert(varchar(50),@dayDiff) + ' Days ' + convert(varchar(50),@hrsDiff)   + ' Hours'

RETURN(convert(varchar(50),@dayDiff) + ' Days ' + convert(varchar(50),@hrsDiff))    + ' Hours'

KẾT THÚC


1
Bạn có thể giải thích mã của bạn theo câu hỏi?
user7294900

1

Sol-1:

select 
  StartTime
  , EndTime
  , CONVERT(NVARCHAR,(EndTime-StartTime), 108) as TimeDiff 
from 
  [YourTable]

Sol-2:

select 
  StartTime
  , EndTime
  , DATEDIFF(hh, StartTime, EndTime)
  , DATEDIFF(mi, StartTime, EndTime) % 60 
from 
  [YourTable]

Sol-3:

select 
  DATEPART(hour,[EndTime]-[StartTime])
  , DATEPART(minute,[EndTime]-[StartTime]) 
from 
  [YourTable]

Datepart hoạt động tốt nhất


1

Vui lòng kiểm tra thủ thuật dưới đây để tìm chênh lệch ngày giữa hai ngày

 DATEDIFF(DAY,ordr.DocDate,RDR1.U_ProgDate) datedifff

nơi bạn có thể thay đổi theo yêu cầu của bạn khi bạn muốn chênh lệch ngày hoặc tháng hoặc năm hoặc thời gian.


0

Đối với tôi Điều này hoạt động Hoàn hảo Chuyển đổi (varchar (8), DATEADD (SECOND, DATEDIFF (SECOND, LogInTime, LogOutTime), 0), 114)

và Đầu ra là HH: MM: SS được hiển thị chính xác trong trường hợp của tôi.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.