■96369 / inTopicNo.5) |
Re[3]: 時間の差をミリ秒で求める |
□投稿者/ 魔界の仮面弁士 (2913回)-(2020/11/17(Tue) 10:40:50)
|
■No96365 (夜叉姫 さん) に返信
> 2020/11/17(Tue) 08:55:02 編集(投稿者)
>
> DECLARE @ETIME DATETIME = '2020-12-31 23:59:59.999';
No96351 でも述べましたが、上記の記述には問題があります。
DATETME 型の精度においては、上記の末尾は .997 または .000 の何れか近いに丸められるため、
結果的に、下記の @ETIME2 相当の時刻として保持されることになります。
DECLARE @ETIME1 DATETIME = '2020-12-31 23:59:59.997';
DECLARE @ETIME2 DATETIME = '2021-01-01 00:00:00.000';
秒未満の値を小数点以下 3 桁精度で保持したいのであれば、このようにします。
DECLARE @ETIME DATETIME2(3) = '2020-12-31 23:59:59.997';
> DECLARE @DFT BIGINT = DATEDIFF_BIG(MILLISECOND, @STIME, @ETIME);
> SQLServer 2016 では対応していないみたいでした。
DATEDIFF_BIG は SQL Server 2016 から搭載された物のはずなのですが…。(2014 や 2012 では非対応)
https://docs.microsoft.com/ja-jp/sql/t-sql/functions/datediff-big-transact-sql?view=sql-server-ver15
当方も SQL Server 2016 ですが、提示されたコードをそのまま貼りつけて実行すると、
DATEDIFF_BIG によって、31622400000 という値が得られました。
「SELECT @@VERSION」の結果が、SQL Server 2016 を指しているにもかかわらず、
『'DATEDIFF_BIG' は 組み込み関数名 として認識されません。』が表示されるのでしょうか?
もしも DATEDIFF のままで処理するなら、
>>> 処理を分けて、「日数差」と「日未満の時刻差」を別々に演算
を行ってみてください。
-- 両者の差は、364日間12時間34分56秒790
DECLARE @S_DateTime DATETIME2(3) = '2020-01-01 23:59:59.999';
DECLARE @E_DateTime DATETIME2(3) = '2020-12-31 12:34:56.789';
DECLARE @SDATE DATE = CAST(@S_DateTime AS DATE);
DECLARE @EDATE DATE = CAST(@E_DateTime AS DATE);
DECLARE @STIME TIME(3) = CAST(@S_DateTime AS TIME);
DECLARE @ETIME TIME(3) = CAST(@E_DateTime AS TIME);
-- 日数部の差。時刻部を切り捨てているので、実際の日数差とは ±24時間弱の誤差が出る。
DECLARE @DAYS INT = DATEDIFF(DAY, @SDATE, @EDATE); -- 今回は 365日間
-- ミリ秒の部の差。-86,399,999 ≦ @MSEC ≦ 86,399,999 の範囲になるハズ。
DECLARE @MSEC INT = DATEDIFF(MILLISECOND, @STIME, @ETIME); -- 今回は -41,103,210 ミリ秒
select @STIME,@ETIME
-- トータルのミリ秒差。
DECLARE @TOTAL_MSEC BIGINT = @DAYS * CAST(86400000 AS BIGINT) + @MSEC
/*
-- マイナス時刻を補正する場合
IF @MSEC < 0
BEGIN
SET @DAYS = @DAYS - 1
SET @MSEC = @MSEC + 86400000
END
*/
-- 365 | -41103210 | 31494896790 あるいは
-- 364 | +45296790 | 31494896790
SELECT @DAYS, @MSEC, @TOTAL_MSEC;
|
|