<< 2024/04 >> | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
|
TDateTime の誤差
15/01/16 17:02 / 開発メモ
ステータスモニターを作成していて、グラフの表示は現在の時刻から線画してという処理になっているのですが、時々誤差が出ます。
リアルタイムに受信しながらテストを行っているので、余り深く考えていなかったのですが、なんか妙におかしなデータになります。 どっかにバグがあるのかと思って、あれこれテストしていたのですが、ふと「これって日付関連の浮動小数点における誤差で出てる?」と思い出して、今までちゃんと確認したことがなかったので適当にテストコードを書いてみる。 var NowDateTime,WDT:TDateTime; i:Integer; Year,Month,Day,Hour,Minute,Second,MSecond:WORD; WSL:TStringList; begin WDT:=Now; DecodeDate(WDT,Year,Month,Day); DecodeTime(WDT,Hour,Minute,Second,MSecond); NowDateTime:=EncodeDateTime(Year,Month,Day,15,0,0,0); WDT:=EncodeDateTime(Year,Month,Day,14,0,0,0); WSL:=TStringList.Create; for i:=0 to 20 do begin WSL.Add(DateTimeToAllStr(NowDateTime)+' / '+DateTimeToAllStr(WDT)+' diff '+Inttostr(MinutesBetween(NowDateTime,WDT))); WDT:=IncMinute(WDT,-1); end; WSL.SaveToFile('time.txt'); WSL.Free; end; DateTimeToAllStr() は yyyy/mm/dd hh:mm:ss と出力するだけの別関数です。 現在の日付の 15:00:00.000 から 14:00:00.000 までの差(MinutesBetween)を最初の20分だけ出力します。 んで結果はこれ。 2015/01/16 15:00:00 / 2015/01/16 14:00:00 diff 59 2015/01/16 15:00:00 / 2015/01/16 13:59:00 diff 60 2015/01/16 15:00:00 / 2015/01/16 13:58:00 diff 62 2015/01/16 15:00:00 / 2015/01/16 13:57:00 diff 63 2015/01/16 15:00:00 / 2015/01/16 13:56:00 diff 64 (以下略) 最初の2行がおかしいですね。 14:00:00.000 から 15:00:00.000 の差は 60分ジャストですが、誤差が出ています。 次の行も同様に誤差が出ていて3行目から正しい結果が出ています。(SecondsBetween でも同様に出る) ***Between を使うことは滅多に無い(あったとしても前回から60分経過しているかなー?程度の精度でしか使わない)のですが、今回は1分単位で集計を行うようなコードが必要だった為、深く考えずにコーディングしてしまった落とし穴でした。 (MinuteSpan などを使って端数も合わせて処理すればよさげですが。先に思い出したのが Between関数だったので) まるめ処理かなんかの内部的な仕様かなと思いますが、こんなんで半日潰れてしまいましたよ。 Ps. Delphi の MinutesBetween() のヘルプには MinutesBetween 関数を呼び出すと,2 つの TDateTime 値の差(分数)を取得できます。MinutesBetween は,完全な分(60 秒)だけをカウントします。したがって,MinutesBetween は午前 9 時と午前 9 時 0 分 59 秒 999 ミリ秒の差を 0 として報告します。この場合,1 としてカウントされるには 1 ミリ秒足りません。 15:00:00 と 14:00:00 は完全な60秒でカウントされる60分じゃないんかい!と突っ込みを入れたくなりましたが(笑) [更新日付:2015/01/16 17:02:15]
トラックバックを見る(0) Log Link [https://akisoftware.com/cgi-bin/blom.exe?akisoft+sl+aa06b6f5a6291ec25178252d9fede1585b6ab308] TB Link [https://akisoftware.com/cgi-bin/blom.exe?akisoft+tb+aa06b6f5a6291ec25178252d9fede1585b6ab308] 記事へのコメント コメントはありません |
@AKISoftOfficialをフォロー
掲示板 サポートBBS PMailServer BBS アクセスの多い記事
最新記事(カテゴリ別)
PMailServer2 Version 2.53 をリリースしました。
04/08 00:50 フリー版からの製品版移行時の MTA 並列数について 02/17 23:52 メールサーバーの開発を始めて20年 02/07 21:46 PMailServer2 Version 2.52a をリリースしました。 12/26 14:02 PMailServer2 Version 2.52 をリリースしました。 10/01 10:48 PMailServer2 Version 2.51b をリリースしました。 09/19 01:43 PMailServer2 Version 2.51b(仮) Memo 09/12 00:33 PMailServer2 Version 2.51a をリリース、及び脆弱性についてのお知らせ 09/05 01:15 PMailServer2 Version 2.51a Memo 08/21 00:48 アドレスV125(K5)のスターターリレーの交換 08/04 10:10 最新コメント
コメントはありません
UUアクセス数
今日は 266回
昨日は 286回 トータル 303854回 3ヶ月記事別ランキング
プロフィール
Z80から68系、8086系を経由して
Pascalに移行。現在は Delphiをメインに C/C#も囓ってみたり。 「無い物は作れ」の精神で年がら年中なにかを作っています。 すぐ自前で作りたがるので無駄に工数が上がったりして自爆してみたりもします。 好きな物は麺類とお煎餅 Blom内検索
BLOM Version 1.39 ©2007-15 A.K.I Software all rights reserved. |