Link to home
Start Free TrialLog in
Avatar of minnirok
minnirok

asked on

Compare file time structures, urgent.

Hi,

I want to delete a file if it is more than 2 weeks old. First I find the file using FindFirstFile/FindNextFile(). The WIN_32_FIND_DATA structure I pass to it is already filled in with its file creation time. (ftCreationTime).

I want to represent 'now' as a similar structure, and my threshold of two weeks as the same structure, so I can just do the following:

if (filetimeNow - filetimeTwoWeeks > filetimeFileCreationTime)
    // Delete the file.


Here is my current framework, this is urgent and I would appreciate any help spelled out clearly, thanks.

if ((hFile = FindFirstFile(szPathBuffer, &w32fd)) != INVALID_HANDLE_VALUE) {

        if (w32fd.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) {

            // Here please help me do the comparison.

        }
}
Avatar of Axter
Axter
Flag of United States of America image

Hi minnirok,
Is this an MFC project, or non-MFC?

Cheers!
Avatar of minnirok
minnirok

ASKER

non MFC, plain ol win32.
'FILETIME' is basically a 64-bit integer packed into a struct. So you can just

__int64 llNow;
__int64 llTwoWeeks;
__int64 llCreationTime;

memcpy ( &llNow, &filetimeNow, sizeof ( __int64));
memcpy ( &llTwoWeeks, &filetimeTwoWeeks , sizeof ( __int64));
memcpy ( &llCreationTime, &filetimeFileCreationTime, sizeof ( __int64));

if (llNow- llTwoWeeks > llCreationTime)
   // Delete the file.
minnirok,
If you have an MFC project, then you can use CTimeSpan class
Or, a bit easier

__int64* pllNow;
__int64* p llTwoWeeks;
__int64* p llCreationTime;

pllNow = &filetimeNow;
pllTwoWeeks = &filetimeTwoWeeks ;
pllCreationTime = &filetimeFileCreationTime;

if (*pllNow- *pllTwoWeeks > *pllCreationTime)
  // Delete the file.
Ooops, that should be

__int64* pllNow;
__int64* pllTwoWeeks;
__int64* pllCreationTime;
Great guys, one last question - the value of pllTwoWeeks is supposed to be whatever number would represent two weeks' time.

How is that number represented in a FILETIME struct? Is that even possible, since msdn says a FILESTRUCT is really just supposed to be the number of 100-nanosecond intervals since January 1, 1601.

For example:

if (*pllNow - (two weeks worth of 100 nano second intervals?) > *pllCreationTime)
    // ...

Do I just need to figure out how many 100 nano second intervals are in two weeks?
>>msdn says a FILESTRUCT is really just supposed to be the number of 100-nanosecond intervals since January 1, 1601.

That's it. You'd get the current SYSTEMTIME, add 14*24*60*60*10^7 to the __int64 value and call 'SystemTimeToFileTime()' to obtain the value that it'd be in two weeks.
E.g.

__int64 llTwoWeeksDelta = 14*24*60*60*100000000;
__int64* pll;
SYSTEMTIME stCur;

GetSystemTime ( &stCur)

pll = &stCur;
*pll += llTwoWeeksDelta;

FILETIME filetimeTwoWeeks;

SystemTimeToFileTime ( &stCur, &filetimeTwoWeeks );
> __int64 llTwoWeeksDelta = 14*24*60*60*100000000;

I've been tripped up by this in some languages where integer constants participate in integer sized math, not __int64 math.

Perhaps it would be safer to explicitly force the 64-bit arithmetic with some casts?


Hi guys,

Ok this is what I've put together, can you please let me know if it is safe/correct? In reality, I will let the user choose an expiration time instead of statically choosing 2 weeks (14 days). So nExpirationTime represents the number of days chosen:


void DoComparison(int nExpirationTime, FILETIME &ftCreationTime)
{
    SYSTEMTIME stNow;
    FILETIME ftCreationTimePlusExpirationTime;

    // This is when the file was created.
    __int64 *pllCreationTimeExpirationTime = &ftCreationTime + (nExpirationTime * 24 * 60 * 60 * 1000000000);

    // Get the current date.
    GetSystemTime (&stNow)

    // Format the current time into a 64 bit value for comparison.
    __int64 *pllNow = &stNow;

    // Is the current date greater than the creation time plus nStudyLifeTime?
    if (*pllNow > *pllCreationTimeExpirationTime) {
        DeleteStudyFolder();
}
>>Perhaps it would be safer to explicitly force the 64-bit arithmetic with some casts?

The above should work with VC++, but just in case:

__int64 llTwoWeeksDelta = 14L*24L*60L*60L*100000000L;

Um,

>>    __int64 *pllCreationTimeExpirationTime = &ftCreationTime + (nExpirationTime * 24 * 60 * 60 * 1000000000);

Will not even compile - that should be

__int64 *pllCreationTimeExpirationTime = *((__int64*)&ftCreationTime) + (nExpirationTime * 24 * 60 * 60 * 1000000000);

The rest looks OK.
Oh but this generates an error:

__int64 *pllCreationTimeExpirationTime = *((__int64*)&ftCreationTime) + (nExpirationTime * 24 * 60 * 60 * 1000000000);


However if I get rid of the extra * surrounding &ftCreationTime it compiles ok:

__int64 *pllCreationTimeExpirationTime = (__int64*)&ftCreationTime + (nExpirationTime * 24 * 60 * 60 * 1000000000);

Is that alright?

Um, sorry, that should have been

__int64 *pllCreationTimeExpirationTime;

* pllCreationTimeExpirationTime = *((__int64*)&ftCreationTime) + (nExpirationTime * 24 * 60 * 60 * 1000000000);

The other line means adding pointers, and that's not what you want to do.
Isn't:

__int64 *pllCreationTimeExpirationTime;
*pllCreationTimeExpirationTime = *((__int64*)&ftCreationTime) + (nExpirationTime * 24 * 60 * 60 * 1000000000);


equivalent to:

__int64 *pllCreationTimeExpirationTime = *((__int64*)&ftCreationTime) + (nExpirationTime * 24 * 60 * 60 * 1000000000);

???

Hi jkr,

This is what I have now, but it will cause an exception error depending on which way I alter the assignment of the __int64 pointers.

void DoComparison(int nExpirationTime, FILETIME &ftCreationTime)
{
    SYSTEMTIME stNow;

    // This is when the file was created.
    __int64 *pllCreationTimePlusExpirationTime = (__int64*)&ftCreationTime + (nExpirationTime* 24L * 60L * 60L * 1000000000L);

    // Get the current date.
    GetSystemTime(&stNow);

    // Format the current time into a 64 bit value for comparison.
    __int64 *pllNow = (__int64*)&stNow;

    // NOTE: crashes checking the below statement:
    if (*pllNow > *pllCreationTimePlusExpirationTime) {
        DeleteStudyFolder();
    }
}

If I change the assignment of pllCreationTimePlusExpirationTime to the way you posted above, it crashes at the assignement:

__int64 *pllCreationTimeExpirationTime;
* pllCreationTimeExpirationTime = *((__int64*)&ftCreationTime) + (nExpirationTime * 24 * 60 * 60 * 1000000000);
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial