更新日付との比較について

解決


  2005-09-05 21:29:52  No: 17391

「2005/09/05 11:20:56」に更新されたファイルと、時刻「2005/09/05 11:20:58」を比較したところ、「datetime = searchrec.Time」になってしまいます(同じ値)。
2秒ずれていますので、検出いたいのですが、うまくいきません。
上記症状の解決方法はありますでしょうか?

また、出来れば文字列「'2005/09/05 11:20:58'」をわざわざ「Tdatetime」に変換することなく比較できればとも思います。
イメージ:datetime := [何かの関数]('2005/09/05 11:20:58');

よろしくお願いします。

var
  datetime : integer;
  searchrec : TSearchRec;
  dt : Tdatetime;
begin
  dt:= StrToDateTime('2005/09/05 11:20:58');
  datetime:= DateTimeToFileDate(dt);

  if FindFirst('ファイル名',faAnyFile, searchrec)=0 then begin
    if datetime <= searchrec.Time then begin
      {処理}
    end;
  end;
end;


Syake  2005-09-06 02:18:10  No: 17392

ABC.Txt(2005年9月1日、9:27:17)

//.....
var
   d1,d2 :Integer;
   searchrec :TSearchRec;
begin
   d1 := DateTimeToFileDate(StrToDateTime('2005/09/01 9:27:10'));
   if FindFirst('c:\ABC.txt',faAnyFile, searchrec)=0 then
   begin
      d2 := searchrec.Time;
      if d1 <= d2 then begin
         {処理}
      end;
   end;
end;
同じにはなりませんけど・・・


Syake  2005-09-06 02:34:19  No: 17393

たびたび・・・
ちなみに、先程の変数[d2]は確認の為に用意したもので
無くても上手くいってます。
また、処理内で使わなければ
var
   searchrec :TSearchRec;
begin
   if FindFirst('c:\ABC.txt',faAnyFile, searchrec)=0 then
   begin
      if StrToDateTime('2005/09/01 9:27:10') <= FileDateToDateTime(searchrec.Time) then
      begin
         //処理、処理、処理
      end;
   end;
end;
でも、上手くいきます。(はずです)


  2005-09-06 22:41:29  No: 17394

Syakeさんありがとうございます。

実は上記PGで、更新日付「2005/09/05 11:20:56」と、時刻「2005/09/05 11:20:58」を比較していますが、時刻「2005/09/05 11:21:00」(さらに2秒後)であれば、うまくいきます。
つまり "ある変わり目" 以内だと同じになってしまいます。
今のところ、解決できていません・・・


  2005-09-06 23:06:24  No: 17395

自分なりに調べてみた結果を記載しておきます。
DateTimeToFileDate(StrToDateTime('2005/09/05 11:20:59')) → 858086045
DateTimeToFileDate(StrToDateTime('2005/09/05 11:20:58')) → 858086045
DateTimeToFileDate(StrToDateTime('2005/09/05 11:20:57')) → 858086044
DateTimeToFileDate(StrToDateTime('2005/09/05 11:20:56')) → 858086044
DateTimeToFileDate(StrToDateTime('2005/09/05 11:20:55')) → 858086043
DateTimeToFileDate(StrToDateTime('2005/09/05 11:20:54')) → 858086043

ちなみにWindowsXP PRO SP2で、ファイルを右クリックからのプロパティで、更新日付「2005/09/05 11:20:56」のファイルの「searchrec.Time」には、「858086045」が取得されますので
DatetimeToStr(FileDateToDateTime(searchrec.Time)) → 「2005/09/05 11:20:58」
DatetimeToStr(FileDateToDateTime(858086045)) → 「2005/09/05 11:20:58」
となりますので、バグ、または精度の限界なのかも知れません。

この方法で5秒以内の精度で比較するな、っていうところでしょうか。


にしの  2005-09-06 23:31:09  No: 17396

FileDateは、DOSの頃からの仕様で、2秒ごとの値なのではないでしょうか。
正確に取得するには、searchrec.FindData.ftLastWriteTimeを使うとよいかと。
例えば、
Timeの値は、2005/09/06 14:30:24だったとき、
ftLastWriteTimeの値は、2005/9/6 14:30:22'516でした。


  2005-09-07 00:25:51  No: 17397

にしのさん、ありがとうございます。
やはりそういう仕様なんでしょうか。
.FindData.ftLastWriteTimeを使ってみたいと思います。

ところで、DateTimeToFileTime関数が未定義と出てしまうんですが、
Delphiのバージョンが古いからですかね...
ちなみにv.4で、uses FileNameCtrls で見つからないそうです。
なんだか持ち替えばかりでスマートじゃないですが、こんな感じでしょうか。

var
  SysTime : SystemTime;
  dt0, dt1: datetime;
begin
  dt0:= StrToDateTime('2005/09/05 11:20:58');

  if FindFirst('ファイル名',faAnyFile, searchrec)=0 then begin
    FileTimeToSystemTime(searchrec.FindData.ftLastWriteTime, SysTime);
    dt1:= SystemTimeToDateTime(SysTime);

    if (dt > dt1) then begin
      {処理}
    end;
  end;
end;


にしの  2005-09-07 01:35:08  No: 17398

FileTimeToLocalFileTimeで、ローカル日付に戻す必要があります。
1.FileTimeToLocalFileTime
2.FileTimeToSystemTime
3.SystemTimeToDateTime
の順ですね。
ただ、これでもdtとdt1は食い違うようです。SystemTimeToDateTimeの仕様かも。
# D7で確認

Timeから取得した日時=2005/09/06 16:29:04
SystemTimeから生成した日時=2005/9/6 16:29:3'591
DateTimeに変換すると=2005/09/06 16:29:03

SystemTimeToDateTimeで、ミリ秒が切り捨てられているようです。

Timeから取得した日時=2005/09/06 16:29:04
SystemTimeから生成した日時=2005/9/6 16:29:3'388
DateTimeに変換すると=2005/09/06 16:29:03
こういうパターンもあるということは、切り上げですかね。

ちなみに、
Timeから取得した日時=2005/09/06 16:29:04
SystemTimeから生成した日時=2005/9/6 16:29:4'0
DateTimeに変換すると=2005/09/06 16:29:04
というパターンもあるので、0ミリ秒であれば+1秒する必要はありません。


  2005-09-07 01:44:16  No: 17399

にしのさん、ありがとうございます。
ほんとわかりやすいご説明でした。
もともとの表示がすでに、切り上げされているんですねぇ。
今のところ、ミリ秒単位で制御の必要がないので、幸いですが(w

最後に一点だけ、ローカルに直す必要があるとのお話でしたけども、これはなぜ必要なのか教えていただけますか?
一応簡単なテストでは、FileTimeToLocalFileTime 無しでも、きちんと比較されているようでした。


にしの  2005-09-07 02:44:30  No: 17400

おや?
私の環境では、-9時間の日付が記録されています。
タイムゾーンの設定は、GMT+9:00になっていますか?
グリニッジ標準時になっているのであればFileTimeToLocalFileTimeを使わなくてもよいかと思いますが、他のPCでも同じでしょうか。

このAPIのヘルプはこちら。
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpsysinf/html/_win32_filetimetolocalfiletime.asp


  2005-09-07 03:00:02  No: 17401

> タイムゾーンの設定は、GMT+9:00になっていますか?
GMT+9:00になっていました。
他の環境で実行する際を考えると、FileTimeToLocalFileTime を記入した方がよさそうですね。

にしのさん、最後までお付き合いいただきまして、ほんとにありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加