Pracuję nad programem, który zapisuje metadane daty z plików, takich jak czas utworzenia, czas ostatniej modyfikacji itp. Stara wersja programu jest napisana w języku VBA, a robi coś takiego:IO.File.GetLastAccessTime jest wyłączony o godzinę
Public Function GetFileLastAccessTime(ByVal FilePath As String) As Date
Dim fso As New Scripting.FileSystemObject
Dim f As Scripting.File
Set f = fso.GetFile(FilePath)
GetFileLastAccessTime = f.DateLastAccessed
End Function
Output pliku w pytaniu:
?getfilelastaccesstime("SomePath")
7/30/2010 2:16:07 PM
to wartość dostaję od właściwości plików w systemie Windows Exploder. Szczęście.
Przenoszę tę funkcję do aplikacji VB.Net. Nowy kod:
Public Function GetLastAccessTime(ByVal FilePath As String) As Date
Return IO.File.GetLastAccessTime(FilePath)
End Function
Sama prostota. Dane wyjściowe:
?GetLastAccessTime("SomePath")
#7/30/2010 3:16:07 PM#
Godzinę później.
Obie funkcje działają na tym samym komputerze, sprawdzając ten sam plik. Próbowałem również używać klasy IO.FileInfo z tym samym wynikiem. Sprawdziłem tysiące plików i wszystkie są wyłączone o godzinę. Pozostałe właściwości daty dotyczące czasu utworzenia i czasu ostatniej modyfikacji również są wyłączone o jedną godzinę.
Pomoc!
Zapomniałem wspomnieć w oryginalnym poście, strefa czasowa komputera to CST, a czas letni nie jest obecnie dostępny.
Powtórzyłem problem w systemie Windows 7 w wersji 64-bitowej i w systemie Windows XP w wersji 32-bitowej.
Dzięki.
1/6/2011 zmiana:
Dziękujemy wszystkim, którzy je próbuje obliczyć żądaną datę z UTC używając odpowiednie przesunięcia strefy czasowej. W tej chwili decyduję, że nie jest to warte ryzyka. W przypadku tego konkretnego wymagania biznesowego znacznie lepiej jest powiedzieć, że wartość daty nie jest tym, czego oczekiwałeś, ponieważ tak działa interfejs API. Jeśli spróbuję to "naprawić", to jestem jego właścicielem, a wolałbym nie.
Tylko dla kopnięć Próbowałem używać starego dobrego Scripting.FileSystemObject przez interop. Daje oczekiwane rezultaty, które zgadzają się z Eksploratorem Windows, z około 5-krotnie wyższą wydajnością w porównaniu do System.IO. Jeśli się okaże, że muszę mieć daty pasujące do tego, co posiada Eksplorator Windows, ukąszę kulę i pójdę tą drogą.
Kolejny eksperyment Próbowałem jechał bezpośrednio do funkcji GetFileTime API w KERNEL32 poprzez C#:
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GetFileTime(
IntPtr hFile,
ref FILETIME lpCreationTime,
ref FILETIME lpLastAccessTime,
ref FILETIME lpLastWriteTime
);
które doprowadziły w dokładnie tym samym zachowanie System.IO miał czas był wyłączony przez godzinę z Windows Explorer .
Jeszcze raz dziękuję wszystkim.
Wygląda na to, że problem z czasem letnim oszczędza mi czas: – Flipster
Czas ostatniego dostępu to ziarnistość wynosząca około 1 godziny. Należy również pamiętać, że domyślnie w systemie Windows Vista i nowszych wartość [Ostatni czas dostępu nie jest domyślnie aktualizowana w woluminach NTFS] (http://blogs.technet.com/b/filecab/archive/2006/11/07 /disabling-last-access-time-in-windows-vista-to-improve-ntfs-performance.aspx). –
DST nie działa teraz, ale * działał *, gdy plik był ostatnio modyfikowany. Kto ma rację? Pracuj w UTC, aby uniknąć konieczności zadawania tego pytania. –