На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Определение времени создания, модификации и открытия файла
    Создал файл (прикрепил) и записал в него примерное время создания и модификации:
    ExpandedWrap disabled
      14:54:37 - создание через Shift+F4 в Total Commander в Notepad++
      14:57:30 - сохранение в Notepad++
      15:00:00 - сохранение в Notepad++ после корректировки
    В Windows 10 в свойствах файла на вкладке "Общие":
    ExpandedWrap disabled
      Создан: 19 июля 2023 г.. 14:54:31
      Изменен: 19 июля 2023 г.. 15:00:00
      Открыт:   28 июля 2023 г.. 12:34:00

    В программе:
    ExpandedWrap disabled
      #include <iostream>
      #include <chrono>
      #include <filesystem>
      using namespace std;
      namespace fs = filesystem;
      int main()
      {
        fs::file_time_type ftime = fs::last_write_time("D:\\TestPrograms\\Файл-даты создания и модификации.txt");
        cout << format("Date: {0:%F} Time: {0:%T}", chrono::floor<std::chrono::seconds>(ftime)) << endl;
        system("pause");
        return 0;
      }
    время определяется как 12:00:00 (видимо UTC), а не как локальное. У меня следующие вопросы:
    1. Как получить локальное время?
    2. Как получить время создания файла и время его открытия (как на вкладке Общие в свойствах файла в Windows).
    Помогите, пожалуйста, разобраться.
    Прикреплённый файлПрикреплённый файл____________________________________________________________.zip (500 байт, скачиваний: 30)
    Сообщение отредактировано: tumanovalex -
      Никогда не нужно было, так что пришлось серьёзно покопаться в вопросе.
      В общем, Стандарт никак не определяет, в каком формате что там и как хранится. Он лишь утверждает, что std::filesystem::file_time_type является альясом для std::chrono::time_point<>, который в свою очередь основан на std::chrono::file_clock. Что такое эти самые std::chrono::file_clock и std::filesystem::file_time_type, не специфицируется, что в общем-то и неудивительно. Единственное дополнительное требование предъявляется к last_write_time:
      Цитата
      file_time_type last_write_time(const path& p);
      ...
      The time of last data modification of p, determined as if by the value of the POSIX stat structure member st_mtime obtained as if by POSIX stat().
      Ок, открываем документацию на stat и среди прочего видим, что st_mtime имеет тип time_t и снова отсылку к стандарту IEEE Std 1003.1-2001.
      Оооок, берём свежий стандарт POSIX "Standard for Information Technology — Portable Operating System Interface (POSIX)" (он-лайн просто так нету, PDF дают только зареганным) и там видим:
      Цитата A.4.14 Seconds Since the Epoch
      ...
      Implementations that implement time_t as a signed 32-bit integer will overflow in 2 038. The data size for time_t is as per the ISO C standard definition, which is implementation-defined.
      See also Epoch (on page 17).
      И наконец
      Цитата
      Historically, the origin of UNIX system time was referred to as ‘‘00:00:00 GMT, January 1, 1970’’. Greenwich Mean Time is actually not a term acknowledged by the international standards community; therefore, this term, ‘‘Epoch’’, is used to abbreviate the reference to the actual standard, Coordinated Universal Time.

      Из всего этого следует заключить, что просто так значения std::filesystem::file_time_type трактовать как некие готовые к использованию цифры не следует, их сначала надо сконвертировать к подходящий формат локального времени. Локальное время можно получить из системного через тайм-зоны, системное же из файлового можно длинно через посредство UTC и всякими там to_utc(), to_sys(), а можно проще через clock_cast<>.
      В итоге получим что-то вроде
      ExpandedWrap disabled
        #include <iostream>
        #include <chrono>
        #include <filesystem>
        #include <format>
         
        namespace fs = std::filesystem;
        namespace chr= std::chrono;
         
        int main()
        {
          fs::file_time_type ftime = fs::last_write_time("delMe.cpp");
         
          std::cout << std::format("Date: {0:%F} Time: {0:%H}:{0:%M}:{0:%S}", chr::floor<chr::seconds>(chr::get_tzdb().current_zone()->to_local(chr::clock_cast<chr::system_clock>(ftime)))) << std::endl;
        }
      Сообщение отредактировано: Qraizer -
        Спасибо большое за решение вопроса перевода времени из UTC в локальное! Сам бы я не разобрался. Решение на Си для определения времени создания нашел:
        ExpandedWrap disabled
          #include <sys\stat.h>
          #include <time.h>
          struct stat t_stat;
          stat(fileName, &t_stat);
          struct tm* timeinfo = localtime(&t_stat.st_ctime);
          printf("File time and date: %s", asctime(timeinfo));
        , а вот найти код для времени открытия файла мне не удалось. Хотелось бы все-таки узнать, как получить время создания файла и время его открытия на C++?
          Цитата tumanovalex @
          Хотелось бы все-таки узнать, как получить время создания файла и время его открытия на C++?

          Используйте функцию GetFileInformationByHandle(), которая возвращает информацию в структуру "BY_HANDLE_FILE_INFORMATION" - в ней найдёте всё, что вам нужно (прототип на ассемблере fasm):

          ExpandedWrap disabled
            struct  BY_HANDLE_FILE_INFORMATION
              dwFileAttributes     dd  0
              ftCreationTime       FILETIME
              ftLastAccessTime     FILETIME
              ftLastWriteTime      FILETIME
              dwVolumeSerialNumber dd  0
              nFileSizeHigh        dd  0
              nFileSizeLow         dd  0
              nNumberOfLinks       dd  0
              nFileIndexHigh       dd  0
              nFileIndexLow        dd  0
            ends


          Как видно, бонусом сразу получаем: атрибуты, размер, кол-во ссылок, серийник тома, и время создания/записи/изменения. Время хранится в виде 8-байтного значения (struct FILETIME), и чтобы привести его в читабельный вид, используем FileTimeToSystemTime(). В скрепке файл для тестов..

          Прикреплённый файлПрикреплённый файлFileInfo_By_Handle.zip (990 байт, скачиваний: 44)
          Прикреплённая картинка
          Прикреплённая картинка
          Сообщение отредактировано: core-i7 -
            Мне хотелось бы найти кроссплатформенное решение, а не только для Windows.
            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script execution time: 0,0327 ]   [ 20 queries used ]   [ Generated: 27.04.24, 12:12 GMT ]