「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;
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;
同じにはなりませんけど・・・
たびたび・・・
ちなみに、先程の変数[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;
でも、上手くいきます。(はずです)
Syakeさんありがとうございます。
実は上記PGで、更新日付「2005/09/05 11:20:56」と、時刻「2005/09/05 11:20:58」を比較していますが、時刻「2005/09/05 11:21:00」(さらに2秒後)であれば、うまくいきます。
つまり "ある変わり目" 以内だと同じになってしまいます。
今のところ、解決できていません・・・
自分なりに調べてみた結果を記載しておきます。
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秒以内の精度で比較するな、っていうところでしょうか。
FileDateは、DOSの頃からの仕様で、2秒ごとの値なのではないでしょうか。
正確に取得するには、searchrec.FindData.ftLastWriteTimeを使うとよいかと。
例えば、
Timeの値は、2005/09/06 14:30:24だったとき、
ftLastWriteTimeの値は、2005/9/6 14:30:22'516でした。
にしのさん、ありがとうございます。
やはりそういう仕様なんでしょうか。
.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;
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秒する必要はありません。
にしのさん、ありがとうございます。
ほんとわかりやすいご説明でした。
もともとの表示がすでに、切り上げされているんですねぇ。
今のところ、ミリ秒単位で制御の必要がないので、幸いですが(w
最後に一点だけ、ローカルに直す必要があるとのお話でしたけども、これはなぜ必要なのか教えていただけますか?
一応簡単なテストでは、FileTimeToLocalFileTime 無しでも、きちんと比較されているようでした。
おや?
私の環境では、-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
> タイムゾーンの設定は、GMT+9:00になっていますか?
GMT+9:00になっていました。
他の環境で実行する際を考えると、FileTimeToLocalFileTime を記入した方がよさそうですね。
にしのさん、最後までお付き合いいただきまして、ほんとにありがとうございました。
ツイート | ![]() |