c++qtfileapiqfile

Modify file's lastModified/lastAccessed/created date in Qt


I have an application that copies some files, but during the copy procedure, the last modified, etc dates are changed to the current date & time. On a few forums, I see it is suggested to use the SETFILETIME call from the fileapi.h as specified here on MS docs.

However, a quick search shows these functions are available here in QFileDevice where one can use the setFileTime function with the following FileTime enum. Note, QFile or QFileInfo does not allow modifying these dates & times, only reading these dates & times.

QFileDevice::FileAccessTime 0 When the file was most recently accessed (e.g. read or written to). QFileDevice::FileBirthTime 1 When the file was created (may not be not supported on UNIX). QFileDevice::FileMetadataChangeTime 2 When the file's metadata was last changed. QFileDevice::FileModificationTime 3 When the file was most recently modified.

How can I get a instance of this QFileDevice from say a QFileInfo object or even a QFile object (in this case, QFile inherits from QFileDevice - will a e.g. static_cast<>() help?

ALternatively, should I rather use the Windows FileAPI.h - how can I do this from say some file location and a QDateTime to modify the created or lastModified time?


Solution

  • I must admit that I noticed QFile::setFileTime() the first time due to OPs question. (I never had the necessity to tweak the time stamps of any file written by my S/W.) Out of curiosity, I tried to puzzle this out.

    That's what I got:

    // Qt header:
    #include <QtCore>
    
    // main application
    int main(int argc, char **argv)
    {
      auto showTimeStamps = [](const QFile &file) {
        qDebug() << "File time stamps of" << file.fileName();
        QFileInfo fileInfo(file);
        qDebug() << "birthTime()   :" << fileInfo.birthTime();
        qDebug() << "lastModified():" << fileInfo.lastModified();
        qDebug() << "lastAccessed():" << fileInfo.lastRead();
      };
    
      qDebug() << "Qt Version:" << QT_VERSION_STR;
      { QFile file("test.txt");
        // create test file
        qDebug() << "Write test.txt...";
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
          qDebug() << "Failed to create test.txt!";
          return 1;
        }
        if (file.write("Test.\n") < 0) {
          qDebug() << "Failed to write to test.txt!";
          return 1;
        }
        file.close();
        qDebug() << "Done.";
        // check file time stamps initially
        showTimeStamps(file);
        // manipulate file time stamps
        const QDateTime timeStamp(QDate(1970, 5, 1), QTime(6, 0));
        qDebug() << "Modify time stamp of creation of test.txt:";
        if (!file.open(QIODevice::Append | QIODevice::Text)) {
          qDebug() << "Failed to open test.txt!";
          return 1;
        }
        if (!file.setFileTime(timeStamp, QFileDevice::FileBirthTime)) {
          qDebug() << "Failed to modify create time!";
          return 1;
        }
        file.close();
        showTimeStamps(file);
        qDebug() << "Modify time stamp of last modification of test.txt:";
        if (!file.open(QIODevice::Append | QIODevice::Text)) {
          qDebug() << "Failed to open test.txt!";
          return 1;
        }
        if (!file.setFileTime(timeStamp, QFileDevice::FileModificationTime)) {
          qDebug() << "Failed to modify last modified time!";
          return 1;
        }
        file.close();
        showTimeStamps(file);
        qDebug() << "Modify time stamp of last access of test.txt:";
        file.setFileTime(timeStamp, QFileDevice::FileAccessTime);
        if (!file.open(QIODevice::Append | QIODevice::Text)) {
          qDebug() << "Failed to open test.txt!";
          return 1;
        }
        if (!file.setFileTime(timeStamp, QFileDevice::FileAccessTime)) {
          qDebug() << "Failed to modify last access time!";
          return 1;
        }
        file.close();
        showTimeStamps(file);
      }
      // bail out to enable check in File Explorer afterwards
      return 0;
      // delete test file
      { qDebug() << "Delete test.txt...";
        if (!QFile::remove("test.txt")) {
          qDebug() << "Failed to delete test.txt!";
          return 1;
        }
        qDebug() << "Done.";
      }
    }
    

    Output:

    Qt Version: 5.13.0
    Write test.txt...
    Done.
    File time stamps of "test.txt"
    birthTime()   : QDateTime(2020-06-18 08:42:09.983 Mitteleuropõische Sommerzeit Qt::LocalTime)
    lastModified(): QDateTime(2020-06-18 08:42:09.984 Mitteleuropõische Sommerzeit Qt::LocalTime)
    lastAccessed(): QDateTime(2020-06-18 08:42:09.983 Mitteleuropõische Sommerzeit Qt::LocalTime)
    Modify time stamp of creation of test.txt:
    File time stamps of "test.txt"
    birthTime()   : QDateTime(1970-05-01 06:00:00.000 Mitteleuropõische Sommerzeit Qt::LocalTime)
    lastModified(): QDateTime(2020-06-18 08:42:09.984 Mitteleuropõische Sommerzeit Qt::LocalTime)
    lastAccessed(): QDateTime(2020-06-18 08:42:09.983 Mitteleuropõische Sommerzeit Qt::LocalTime)
    Modify time stamp of last modification of test.txt:
    File time stamps of "test.txt"
    birthTime()   : QDateTime(1970-05-01 06:00:00.000 Mitteleuropõische Sommerzeit Qt::LocalTime)
    lastModified(): QDateTime(1970-05-01 06:00:00.000 Mitteleuropõische Sommerzeit Qt::LocalTime)
    lastAccessed(): QDateTime(2020-06-18 08:42:09.983 Mitteleuropõische Sommerzeit Qt::LocalTime)
    Modify time stamp of last access of test.txt:
    File time stamps of "test.txt"
    birthTime()   : QDateTime(1970-05-01 06:00:00.000 Mitteleuropõische Sommerzeit Qt::LocalTime)
    lastModified(): QDateTime(1970-05-01 06:00:00.000 Mitteleuropõische Sommerzeit Qt::LocalTime)
    lastAccessed(): QDateTime(1970-05-01 06:00:00.000 Mitteleuropõische Sommerzeit Qt::LocalTime)
    

    Afterwards I verified the time stamps in the Windows File Explorer:

    snapshot of File Properties for test.txt

    So, I wonder about the claim of OP

    Note, QFile or QFileInfo does not allow modifying these dates & times, only reading these dates & times.

    I had expected that's the actual intention of QFile::setFileTime(), and it seems to work properly on my side.