?
Solved

Compare file time structures, urgent.

Posted on 2005-03-04
18
Medium Priority
?
316 Views
Last Modified: 2008-02-20
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
Comment
Question by:minnirok
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 5
  • 2
  • +2
18 Comments
 
LVL 30

Expert Comment

by:Axter
ID: 13461597
Hi minnirok,
Is this an MFC project, or non-MFC?

Cheers!
0
 
LVL 7

Author Comment

by:minnirok
ID: 13461645
non MFC, plain ol win32.
0
 
LVL 86

Expert Comment

by:jkr
ID: 13461672
'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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 30

Expert Comment

by:Axter
ID: 13461676
minnirok,
If you have an MFC project, then you can use CTimeSpan class
0
 
LVL 86

Expert Comment

by:jkr
ID: 13461689
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
 
LVL 86

Expert Comment

by:jkr
ID: 13461694
Ooops, that should be

__int64* pllNow;
__int64* pllTwoWeeks;
__int64* pllCreationTime;
0
 
LVL 7

Author Comment

by:minnirok
ID: 13461854
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
 
LVL 86

Expert Comment

by:jkr
ID: 13461899
>>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
 
LVL 86

Expert Comment

by:jkr
ID: 13461927
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
 
LVL 22

Expert Comment

by:grg99
ID: 13462110
> __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
 
LVL 7

Author Comment

by:minnirok
ID: 13462213
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
 
LVL 86

Expert Comment

by:jkr
ID: 13462222
>>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
 
LVL 86

Expert Comment

by:jkr
ID: 13462237
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
 
LVL 7

Author Comment

by:minnirok
ID: 13462288
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
 
LVL 86

Expert Comment

by:jkr
ID: 13462299
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
 

Expert Comment

by:AlreadyGoogled
ID: 13462392
Isn't:

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


equivalent to:

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

???

0
 
LVL 7

Author Comment

by:minnirok
ID: 13462531
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
 
LVL 86

Accepted Solution

by:
jkr earned 2000 total points
ID: 13462626
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

[Webinar] How Hackers Steal Your Credentials

Do You Know How Hackers Steal Your Credentials? Join us and Skyport Systems to learn how hackers steal your credentials and why Active Directory must be secure to stop them.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question