• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 321
  • Last Modified:

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.

        }
}
0
minnirok
Asked:
minnirok
  • 9
  • 5
  • 2
  • +2
1 Solution
 
AxterCommented:
Hi minnirok,
Is this an MFC project, or non-MFC?

Cheers!
0
 
minnirokAuthor Commented:
non MFC, plain ol win32.
0
 
jkrCommented:
'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.
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
AxterCommented:
minnirok,
If you have an MFC project, then you can use CTimeSpan class
0
 
jkrCommented:
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.
0
 
jkrCommented:
Ooops, that should be

__int64* pllNow;
__int64* pllTwoWeeks;
__int64* pllCreationTime;
0
 
minnirokAuthor Commented:
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?
0
 
jkrCommented:
>>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.
0
 
jkrCommented:
E.g.

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

GetSystemTime ( &stCur)

pll = &stCur;
*pll += llTwoWeeksDelta;

FILETIME filetimeTwoWeeks;

SystemTimeToFileTime ( &stCur, &filetimeTwoWeeks );
0
 
grg99Commented:
> __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?


0
 
minnirokAuthor Commented:
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();
}
0
 
jkrCommented:
>>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;

0
 
jkrCommented:
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.
0
 
minnirokAuthor Commented:
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?

0
 
jkrCommented:
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.
0
 
AlreadyGoogledCommented:
Isn't:

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


equivalent to:

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

???

0
 
minnirokAuthor Commented:
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);
0
 
jkrCommented:
Sorry, but this is getting a bit confusing regarding pointers and addresses :o)

The whole thing should be

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

   // This is when the file was created.
   __int64 llCreationTimePlusExpirationTime = *((__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 > llCreationTimePlusExpirationTime) {
       DeleteStudyFolder();
   }
}
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 9
  • 5
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now