Столкнулся с данной проблемой еще год назад, но отложит решение… теперь вопрос опять актуален для меня.
Проявляется на Windows (установлен Python 2.7.3), на Linux все нормально.
Допустим есть файл, который изменен “2008-12-16 07:55:22” (это локальное время).
Файловые менеджеры (Explorer и T-Commander) показывают время корректно, а вот Python выдает “2008-12-16 08:55:22”.
написал год назад тестовый код:
# -*- coding: utf-8 -*- import logging, sys, os, hashlib, struct, time from os import path from datetime import datetime def getFileTimes(fname, gmt=True, checkMT=True): try: fs = "%Y-%m-%d %H:%M:%S" os.stat_float_times(False) if gmt: ct = time.gmtime(os.path.getctime(fname)) mt = time.gmtime(os.path.getmtime(fname)) else: ct = time.localtime(os.path.getctime(fname)) mt = time.localtime(os.path.getmtime(fname)) if checkMT: pass # TODO: if ct > mt: ct = mt return time.strftime(fs,ct), time.strftime(fs,mt) except: return "", "" files = { 'test-file-1-ERR-js.txt': '2009-11-29 21:27:38', 'test-file-2-OK-js.txt' : '2009-05-27 10:46:12', 'test-file-3-ERR-js.txt': '2008-12-16 09:55:22', # после отмены перехода 'test-file-4-OK-py.txt' : '2011-11-22 10:33:44', 'test-file-5-OK-txt.txt': '2012-07-20 20:05:29' } for fname in files.keys(): ftime = getFileTimes(fname, False)[1] ftime2 = getFileTimes(fname, True)[1] shift = int(ftime[11:13]) - int(ftime2[11:13]) res = 'OK: ' if files[fname] == ftime else 'ERR:' print '%s [%s] ftime = %s mustbe = %s shift=%i' % (res, fname, ftime, files[fname], shift)
а также попробовал то же самое через WinAPI,
через API-функции винда выдает всё нормально
код на С++:
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
BOOL GetLastWriteTime(HANDLE hFile, LPTSTR lpszString, DWORD dwSize)
{
FILETIME ftCreate, ftAccess, ftWrite;
SYSTEMTIME stUTC, stLocal;
DWORD dwRet;
// Retrieve the file times for the file.
if (!GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite))
return FALSE;
// Convert the last-write time to local time.
FileTimeToSystemTime(&ftWrite, &stUTC);
SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);
// Build a string showing the date and time.
dwRet = StringCchPrintf(lpszString, dwSize, TEXT(
"%04d-%02d-%02d %02d:%02d:%02d"), stLocal.wYear, stLocal.wMonth,
stLocal.wDay, stLocal.wHour, stLocal.wMinute, stLocal.wSecond);
if (S_OK == dwRet)
return TRUE;
else
return FALSE;
}
int _tmain(int argc, TCHAR *argv[])
{
HANDLE hFile;
TCHAR szBuf[MAX_PATH];
if (argc != 2)
{
printf("This sample takes a file name as a parameter\n");
return 0;
}
hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("CreateFile failed with %d\n", GetLastError());
return 0;
}
if (GetLastWriteTime(hFile, szBuf, MAX_PATH))
_tprintf(TEXT("%s"), szBuf);
CloseHandle(hFile);
}
код на Python:
# -*- coding: utf-8 -*- import logging, sys, os, hashlib, struct, time from os import path from datetime import datetime files = { 'test-file-1-ERR-js.txt': '2009-11-29 21:27:38', 'test-file-2-OK-js.txt' : '2009-05-27 10:46:12', 'test-file-3-ERR-js.txt': '2008-12-16 09:55:22', # после отмены перехода 'test-file-4-OK-py.txt' : '2011-11-22 10:33:44', 'test-file-5-OK-txt.txt': '2012-07-20 20:05:29', 'test-file-6.txt': '2013-02-20 19:32:10' } for fname in files.keys(): import subprocess proc = subprocess.Popen('"getFileTime/getFileTime.exe" "%s"' % fname, shell=True, stdout=subprocess.PIPE) out = proc.stdout.readlines() ftime = out[0] shift = 0 res = 'OK: ' if files[fname] == ftime else 'ERR:' print '%s ftime = %s mustbe = %s [%s] shift=%i' % (res, ftime, files[fname], fname, shift)
P.S.
Еще раз спасибо Диме Медведеву за его Великие Реформы.