C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.96346 の関連記事表示

<< 0 >>
■96346  時間の差をミリ秒で求める
□投稿者/ 夜叉姫 -(2020/11/12(Thu) 14:27:46)

    分類:[.NET 全般] 

    SQLServerにて
    ETIME が 2020-12-25 08:00:00 の時は
    どうすれば求まりますか?

    DECLARE @STIME DATETIME = '2020-11-11 20:00:00.000';
    DECLARE @ETIME DATETIME = '2020-11-13 08:00:00.000';
    --DECLARE @ETIME DATETIME = '2020-12-25 08:00:00.000';

    DECLARE @DFT INT = DATEDIFF(MILLISECOND, @STIME, @ETIME) / 3;

    DECLARE @TM1 DATETIME = DATEADD(MILLISECOND, @DFT * 0, @STIME);
    DECLARE @TM2 DATETIME = DATEADD(MILLISECOND, @DFT * 1, @STIME);
    DECLARE @TM3 DATETIME = DATEADD(MILLISECOND, @DFT * 2, @STIME);
    DECLARE @TM4 DATETIME = DATEADD(MILLISECOND, @DFT * 3, @STIME);

    SELECT @TM1, @TM2, @TM3, @TM4
親記事 /過去ログ167より / 関連記事表示
削除チェック/

■96351  Re[1]: 時間の差をミリ秒で求める
□投稿者/ 魔界の仮面弁士 -(2020/11/12(Thu) 16:05:25)
    No96346 (夜叉姫 さん) に返信
    > 分類:[.NET 全般] 
    > SQLServerにて

    であれば、[.NET 全般]ではなく、[データベース全般]が適切かと。
    あるいは [その他の言語] とか。


    > DECLARE @STIME DATETIME = '2020-11-11 20:00:00.000';
    > DECLARE @ETIME DATETIME = '2020-11-13 08:00:00.000';
    > --DECLARE @ETIME DATETIME = '2020-12-25 08:00:00.000';
    > DECLARE @DFT INT = DATEDIFF(MILLISECOND, @STIME, @ETIME) / 3;

    MILLISECOND を指定されていますが、DATETIME 型の精度は 1/1000 秒ではありません。
    秒未満の小数点以下(3 桁目まで)は、「.xx0」「.003」「.007」のいずれかなのでご注意を。

    ミリ秒精度を求めるなら、DATETIME2 型が使えます。(こちらは 100 ナノ秒精度)

    …それはさておき。


    DATEDIFF は INT 精度なので、
    MILLISECOND 指定で求められる範囲は
    24日20時間31分23.647 が上限です。

    これを SECOND 指定に切り替えれば、68年分ぐらいまで耐えられるでしょう。


    とはいえ、今回欲しいのは「ミリ秒」の差なのですよね。

    もしも MILLISECOND での指定が必要であれば、
     DECLARE @DFT BIGINT = DATEDIFF_BIG(MILLISECOND, @STIME, @ETIME);
    という方法はあります。


    ただし、対応する DATEADD_BIG 関数があるわけではありませんので、
    その点は注意が必要です。(DATEADD は INT 精度)


    本当にミリ秒指定での算出が必要なら、処理を分けて、
    「日数差」と「日未満の時刻差」を別々に演算してみてください。
記事No.96346 のレス /過去ログ167より / 関連記事表示
削除チェック/

■96365  Re[2]: 時間の差をミリ秒で求める
□投稿者/ 夜叉姫 -(2020/11/17(Tue) 08:47:42)
    2020/11/17(Tue) 09:33:39 編集(投稿者)

    No96351 (魔界の仮面弁士 さん) に返信

    遅くなって申し訳ありません。

    DECLARE @STIME DATETIME = '2020-01-01 0:0:0.000';
    DECLARE @ETIME DATETIME = '2020-12-31 23:59:59.999';

    DECLARE @DFT BIGINT = DATEDIFF_BIG(MILLISECOND, @STIME, @ETIME);

    SELECT @DFT

    上記実行すると
    以下のエラーメッセージが表示されます。

    メッセージ 195、レベル 15、状態 10、行 4
    'DATEDIFF_BIG' は 組み込み関数名 として認識されません。
    メッセージ 137、レベル 15、状態 2、行 6
    スカラー変数 "@DFT" を宣言してください。

    追記
    SQLServer 2016 で対応みたいでした。
    使用している SQLServer は 2012 なので使えませんでした。
記事No.96346 のレス /過去ログ167より / 関連記事表示
削除チェック/

■96366  Re[3]: 時間の差をミリ秒で求める
□投稿者/ 通りすがり -(2020/11/17(Tue) 10:15:24)
    No96365 (夜叉姫 さん) に返信
    バージョン低いなら基礎構文で組み上げるしか無い訳で
    その情報は全部出てると思うんだけど、全部試したのかな?

    DECLARE @STIME DATETIME2 = '2020-12-31 0:0:0.000';
    DECLARE @ETIME DATETIME2 = '2020-12-31 23:59:59.999';
    SELECT DATEDIFF(MS, @STIME, @ETIME) AS [列1]
記事No.96346 のレス /過去ログ167より / 関連記事表示
削除チェック/

■96369  Re[3]: 時間の差をミリ秒で求める
□投稿者/ 魔界の仮面弁士 -(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;
記事No.96346 のレス /過去ログ167より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -