Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Ошибка FileDateToDateTime()


Автор: Stibrus 28.3.2006, 13:36
Добрый день!
Может быть, кто-нибудь сталкивался с той проблемой, что FileDateToDateTime ( FileAge ( FileName ) ) иногда ошибается на 1-2 секунды?
И может, кто-нибудь придумал, как это лечить?

Мне надо преобразовать дату модификации в строку, а иного пути выйти на DateTimeToStr нет

Заранее спасибо!

Автор: Romikgy 28.3.2006, 13:47
Код

ChangeDate.Caption := 
      DateTimeToStr(FileDateToDateTime(FileAge(FileList.FileName)));


вот так в хелпе
Цитата(Stibrus @ 28.3.2006, 12:36 Найти цитируемый пост)
иногда ошибается на 1-2 секунды?

1. это существено?
2. А как проверяешь что есть ошибка?

Автор: Stibrus 28.3.2006, 19:45
Задачка, связанная с CVS
CVS считает, что файл изменен, если строка даты/времени файла, хранящаяся в служебном файле CVS/Entries, не совпадает с точностью до секунд с датой/временем изменения файла (с учетом разницы с GMT). На этом ошибка и была поймана - при приведении даты/времени в служебном файле к той дате/времени, которую выдает FileAge, выскакивает ошибка в 1 секунду (один раз заметил 2). Ошибка встречается примерно в 5% случаев.

Это я рассказал к тому, что проблема действительно довольно существенная smile

Автор: Poseidon 28.3.2006, 20:44
Обычно, слежение за изменен/не изменен файл делается не по дате последнего изменения, а по контрольной сумме (CRC) файла

Автор: Romikgy 29.3.2006, 08:57
Stibrus, давай определимся
Цитата(Stibrus @ 28.3.2006, 18:45 Найти цитируемый пост)
если строка даты/времени файла, хранящаяся в служебном файле CVS/Entries

почему ты считаешь что это является правильнее чем

Цитата(Stibrus @ 28.3.2006, 18:45 Найти цитируемый пост)
дате/времени, которую выдает FileAge

Это?

Цитата(Stibrus @ 28.3.2006, 18:45 Найти цитируемый пост)
с точностью до секунд

И зачем такая точность?

Цитата(Stibrus @ 28.3.2006, 18:45 Найти цитируемый пост)
CVS

Я не совсем знаю , что это такое, подозреваю прога для слежения за исходниками, я прав?

Автор: Snowy 29.3.2006, 09:27
Цитата(Romikgy @ 29.3.2006, 08:57 Найти цитируемый пост)
Я не совсем знаю , что это такое, подозреваю прога для слежения за исходниками, я прав?
Control Version System.
Система контроля версий.

Проверить кто прав легко. Просто взять найденный файл и посмотреть его св-ва, как их показывает винда.
Это и будет правильный результат.

Автор: Stibrus 29.3.2006, 10:30
Snowy , все совершенно верно, так я и "поймал" ошибку.
2 Romikgy: CVS - система слежения за версиями исходных файлов, крайне полезная когда над проектом работает группа разработчиков.


Немножко углубляясь в задачу, скажу, что мне надо было сделать так, чтобы WinCVS считал файлы неизмененными. Как я уже говорил ранее, путь для этого только один - проставить в служебном файле реальную дату модификации файла. Тут-то и вышел затык - примерно 5% файлов получили погрешность в строке, представляющей эту дату.

Сравнив в Explorer дату/время модификации файла с CVSными, я убедился, что CVS все делает правильно. Отсюда делаю вывод - ошибается приложение на Дельфи.

Далее - два варианта. Либо ошибается FileAge, но (имхо) это просто невозможно, эта функция работает "напрямую" с системой
А явная причина - ошибка пересчета даты/времени из Integer в Float в FileDateToDateTime

В общем, надо делать свою функцию формирования строки на основании даты/времени, возвращаемой FileAge

Автор: Romikgy 29.3.2006, 11:13
GetFileAttributesEx
GetFileInformationByHandle
может это поможет?
Добавлено @ 11:16
GetFileTime
CompareFileTime

Автор: Stibrus 29.3.2006, 17:26
Помимо GetAge опробованы следующие методы:
1. Через TSearchRec
2. FileGetDate()

Оба дали одинаковый результат (т.е. неудовлетворительный)

Вывод: дело все же в FileDateToDateTime() smile

Автор: Snowy 29.3.2006, 17:57
Код
function GetFileTimeStr(FileName: string): string;
var
  Handle: THandle;
  FindData: TWin32FindData;
  LocalFileTime: TFileTime;
  st: TSystemTime;
begin
  result := '';
  Handle := FindFirstFile(PChar(FileName), FindData);
  if Handle <> INVALID_HANDLE_VALUE then
  begin
    Windows.FindClose(Handle);
    if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
    begin
      FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
      FileTimeToSystemTime(LocalFileTime, st);
      result := Format('%2u.%2u.%4u~%2u:%2u:%2u',
              [st.wDay, st.wMonth, st.wYear, st.wHour, st.wMinute, st.wSecond]);
      result := StringReplace(result, ' ', '0', [rfReplaceAll]);
      result := StringReplace(result, '~', ' ', [rfReplaceAll]);
    end;
  end;
end;


Так мы избегаем погрешностей TDateTime, который, как известно Double.
А Double = погрешность.

Автор: Stibrus 29.3.2006, 19:49
Спасибо, попробую, если все ок - процитирую получившуюся функцию формирования строки в формате CVS (может, кому-нибудь пригодится)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)