いつもお世話になります。C++で開発中です。C++で日付の比較処理を行いたいと考
えています。
例えばあるディレクトリに AというファイルがありAのファイルのタイムスタンプを
取得しこのAのファイルが 現在の日時から何日経過しているかを調べたいのですが(A
のファイルが作成されてからAのファイルのタイムスタンプが更新されないという前提
で)何かいい方法などありませんでしょうか?
現在 tm構造体とlocaltime()で現在の日時を取得しているのですが、単純に日時の
比較などをしていく方法しか思いつかないので もっと手法などがあればご教授して頂
きたいと思います。よろしくお願いいたします。
> tm構造体とlocaltime()で現在の日時を取得しているのですが、単純に日時の
比較などをしていく方法しか思いつかないので
それ以上に確実/堅実な方法が思い浮かびません。
あなたの言うところのいい方法とは?
簡単? 高速? 移植性? なにをもっていいとするのでしょうか?
MFCを使ってもOKで直接的な計算をしないでよい方法をと言う話なら
CTimeクラスとCTimeSpanクラスで何とかなりそうですね。
現在時間が入ったCTimeクラスのインスタンスからファイルのタイムスタンプを
設定したCTimeクラスのインスタンスを差し引けば、その差が入ったCTimeSpanクラスの
インスタンスが手に入ります。
そこから先はCTimeSpanクラスから数値を取得してよしなに処理すればいいだけです。
にしても、
> あなたの言うところのいい方法とは?
> 簡単? 高速? 移植性? なにをもっていいとするのでしょうか?
という点については同感です。
質問する時は具体的な答えが出やすいように問いかけ方を考えた方がいいです。
επιστημηさん。PATIOさん。ありがとうございます。
>あなたの言うところのいい方法とは?
>簡単? 高速? 移植性? なにをもっていいとするのでしょうか?
私は簡単という意味で定義させていただきました。日付比較だとうるう年の計算など
も必要になってくるはずなので・・・
>質問する時は具体的な答えが出やすいように問いかけ方を考えた方がいいです。
すいません。今後気をつけます。
>日付比較だとうるう年の計算なども必要になってくるはずなので・・・
time_t型で値を持てば、difftime関数で簡単に比較できます。
(struct tm型ならmktimeでtime_t型に変換してからdifftime関数を使う)
ただ、ファイルスタンプをどのようにして取得指定のかまったくかかれていないので
単純にdifftimeを使えばいいとは断定できないです。
Blue さん。ありがとうございます。
>ファイルスタンプをどのようにして取得指定のかまったくかかれていないので
ファイルのタイムスタンプはGetFileTime()で取得しようと考えてます。ただ いろい
ろ調べていると FileTimeToSystemTime()というものを使って システム時刻同士で引き
算する方法も使えるのかな??と考えています。
ちょっと調べてみたところ、
FILETIME
↓ FileTimeToLocalFileTime
FILETIME
↓ FileTimeToSystemTime
SYSTEMTIME
↓ 値を代入※
struct tm
↓ mktime
time_t
で time_t型の値を取得して、time&localtimeで取得したtime_t型の値と
difftimeすることになりそう。(参考:MFC CFile,CTimeのソース)
(上の変換が面倒であれば)
SYSTEMTIME同士を計算する関数は用意されていないので、閏年を考慮して自作すること
になるでしょう。
※代入する際に、月と年のstruct tm型での扱いに気をつけなければいけない。
最後に、環境は必ず明記しましょう。
>C++で開発中です。
だけでは不十分です。(というか、この掲示板で質問すればVC++を使うことはデフォルト
になるし。)
MFC(もしくは.NET Framework)を前提にすれば、カナリ簡単にかけますし、前提にしなけ
れば上のように面倒臭くなります。
いろいろ調べてみたところ、
FILETIMEは1601年1月1日からの総100ナノ秒単位の値だそうです。
time_tは1970年1月1日からのそう秒数なので、これから計算で算出させる方法もあるら
しいです。
1601年1月1日~1970年1月1日の総日数は 369 * 365 + 89 と求められます。
FILETIME構造体を__int64型に入れて、10000000で割り、134774 * 24 * 60 * 60を引け
ば計算できそうです。
FILETIME ft;
// ファイル日付の取得
(略)
__int64* temp = ( __int64* )&ft; // というのでいいか微妙。
// 134774 * 24 * 60 * 60 = 11644473600
time_t t = ( time_t )( ( *temp / 10000000 ) - 11644473600 );
(参考)
http://homepage1.nifty.com/dangan/Content/Program/Java/jLHA/Notes/DataNotes.htm
l
SYSTEMTIME同士の計算でやるならSystemTimeToVariantTimeを使うと楽です。
(日付のみの比較の場合は各小数点以下の値を落とす)
Blueさん。subaruさん。ありがとうございます。私の方でも再度調べてみて time_t型の
difftime()へたどり着きました。
>SYSTEMTIME同士の計算でやるならSystemTimeToVariantTime
このような関数があったのですね。もう少し調べてみます。
>最後に、環境は必ず明記しましょう。
非MFCということで単純C++でと書いてしまいました。きちんと環境を明確せず投稿し
てすいません。以後気をつけます。
みなさんありがとうございました。
ちなみに、
>GetFileTime
やFindFirstFileで取得できるのはFILETIMEですが、
システムコール関数の _findfirst,_stat,_fstatではtime_t型の値で取得できます。
(内部では同じようにFILETIMEから変換しているんですけどね。)
#include <ctime>
#include <io.h>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
int main()
{
struct _finddata_t fd;
long hFile;
hFile = _findfirst( __FILE__, &fd );
if ( hFile != -1L )
{
struct tm* wt;
wt = localtime( &fd.time_write );
std::cout << __FILE__ << std::endl
<< asctime( wt ) << std::endl;
_findclose( hFile );
}
struct _stat fs;
if ( _stat( __FILE__, &fs ) == 0 )
{
struct tm* wt;
wt = localtime( &fs.st_mtime );
std::cout << __FILE__ << std::endl
<< asctime( wt ) << std::endl;
}
return 0;
}
time_tは2038年問題があるのであまりお勧めしない