Hi everybody,
I'm trying to make a program to get the file creation or access or modification date, but the program always is returning me this date "Thu Jan 1 01:00:00 1970". I tried lots of codes and heelps from the forum, of posts from other users, but the result is always the same, and I complied the code and run in many machines XP and Win7.

Here you are the code:

bool ListDirectoryContents(const char *sDir) {
WIN32_FIND_DATA fdFile = {0};
HANDLE hFind = NULL;
ULONGLONG fileSize;
time_t rawtime;
struct tm * timeinfo2;


long bsize;
float kbsize;

char sPath[2048];

sprintf(sPath, "%s\\*.*", sDir);

if ((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE) {
printf("Path not found: [%s]\n", sDir);
return false;
}

do {
if (strcmp(fdFile.cFileName, ".") != 0 && strcmp(fdFile.cFileName, "..") != 0) {
sprintf(sPath, "%s\\%s", sDir, fdFile.cFileName);

if (fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
ListDirectoryContents(sPath); 
} else {
cout << "# FILE NAME: ######################################################" << endl;
cout << "File: " << sPath << endl;
cout << "# FILE SIZE INFO: #################################################" << endl;
bsize = fdFile.nFileSizeLow;
kbsize = (float) bsize / 1024;
cout << "SIZE: " << fdFile.cFileName << " " << bsize << " bytes " << kbsize << " kb" << endl;
cout << "size HIGH: " << (fdFile.nFileSizeHigh * (MAXDWORD + 1)) + fdFile.nFileSizeLow << endl;
fileSize = fdFile.nFileSizeHigh;
fileSize <<= sizeof ( fdFile.nFileSizeHigh) * 8;
fileSize |= fdFile.nFileSizeLow;
cout << "fileSize: " << (DWORD) fileSize << endl;
cout << "# FILE ACCESS INFO: ################################################" << endl;
time((time_t*) & fdFile.ftLastAccessTime);
cout << " --> last open: " << ctime((const time_t*) &fdFile.ftLastAccessTime) << endl; 
}
}
} while (FindNextFile(hFind, &fdFile)); 
FindClose(hFind);
return true;
}

int main() {
ListDirectoryContents("C:\\Repository_Files\\");
return 0;
}

Edited 4 Years Ago by txikiting

First, permit me to re-post the code with suitable indentation, courtesy of Astyle:

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include "windows.h"

using std::cout;
using std::endl;

bool ListDirectoryContents(const char *sDir)
{
    WIN32_FIND_DATA fdFile = {0};
    HANDLE hFind = NULL;
    ULONGLONG fileSize;
    time_t rawtime;
    struct tm * timeinfo2;
    long bsize;
    float kbsize;
    char sPath[2048];
    sprintf(sPath, "%s\\*.*", sDir);
    if ((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE)
    {
        printf("Path not found: [%s]\n", sDir);
        return false;
    }
    do
    {
        if (strcmp(fdFile.cFileName, ".") != 0 && strcmp(fdFile.cFileName, "..") != 0)
        {
            sprintf(sPath, "%s\\%s", sDir, fdFile.cFileName);
            if (fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                ListDirectoryContents(sPath);
            }
            else
            {
                cout << "# FILE NAME: ######################################################" << endl;
                cout << "File: " << sPath << endl;
                cout << "# FILE SIZE INFO: #################################################" << endl;
                bsize = fdFile.nFileSizeLow;
                kbsize = (float) bsize / 1024;
                cout << "SIZE: " << fdFile.cFileName << " " << bsize << " bytes " << kbsize << " kb" << endl;
                cout << "size HIGH: " << (fdFile.nFileSizeHigh * (MAXDWORD + 1)) + fdFile.nFileSizeLow << endl;
                fileSize = fdFile.nFileSizeHigh;
                fileSize <<= sizeof ( fdFile.nFileSizeHigh) * 8;
                fileSize |= fdFile.nFileSizeLow;
                cout << "fileSize: " << (DWORD) fileSize << endl;
                cout << "# FILE ACCESS INFO: ################################################" << endl;
                time((time_t*) & fdFile.ftLastAccessTime);
                cout << " --> last open: " << ctime((const time_t*) &fdFile.ftLastAccessTime) << endl;
            }
        }
    }
    while (FindNextFile(hFind, &fdFile));
    FindClose(hFind);
    return true;
}

int main()
{
    ListDirectoryContents("C:\\Repository_Files\\");
    return 0;
}

Now, when I compile and run this (under Code::Blocks, with MinGW GCC 4.7.1), instead of the "Jan 01, 1970" response, I get the current time. I can only conclude that you're using a different compiler, and that the ctime() function is different in your version.

Either way, the cause is the same: the value you are passing to ctime() isn't a valid time_t * value, rather, the value it points to isn't compatible with a time_t value. A time_t is (in most implementations) an unsigned 64-bit value, which measures the microseconds since 1 Jan 1970 (which is why that comes up in your version of the program; this date is known as the Unix time epoch). A FILETIME, on the other hand, is a struct containing two DWORD (signed) time values measuring time in 100s of nanoseconds since 1 Jan 1601. The two values are both 64 bits total, but they are by no means interchangeable.

Unfortunately, there is no easy way to convert the two values between each other. I recommend avoiding ctime() for Windows system times, and instead use the Windows time functions and structures directly. In this case, you would want to call FileTimeToSystemTime() to get a SYSTEMTIME structure, then print out the individual time fields as you need them.

Oh, and you probably want to use fdFile.ftCreationTime rather than fdFile.ftLastAccessTime.

                if (FileTimeToSystemTime(&fdFile.ftCreationTime, &file_creation_time))
                {
                     const char* Months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
                     const char* Weekdays[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
                     cout << " --> file created: "
                         << Weekdays[file_creation_time.wDayOfWeek] << ", "
                         << std::right << file_creation_time.wDay << " "
                         << Months[file_creation_time.wMonth - 1] << " "
                         << file_creation_time.wYear << " "
                         << file_creation_time.wHour << ":" << file_creation_time.wMinute
                         << endl;
                }

Note that, if the file was copied from somewhere else, it appears that it shows the time it was copied as the creation time.

Ok, thank you very much, I will try it today!

You have done an awesome job.

Oh! sorry, I forgot to mention that I'm using the copiler comming from Netbeans, it's named cygwin (I know this is not a compiler, but I guess it is using gcc as you said).

Thank you very much, now it is working properly.

Thanks again, without your help I wont achieve it.

This article has been dead for over six months. Start a new discussion instead.