Wczoraj napisałem kilka słów o różnych timestampach zwracanych przez LogParser dla różnych formatów wejściowych. Dziś jeszcze kilka słów w tym temacie.
I jeszcze o czasie (time_t, FILETIME, TIMESTAMP)...
time_t to typ danych, w którym data jest reprezentowana jako ilość sekund od 1 stycznia 1970 roku (Unix epoch). Co do zasady reprezentowane jako 32 lub 64 bitowy int. Reprezentacja ta ma jeszcze kilka innych "smaczków", które nie bardzo mnie w tej chwili interesują.
FILETIMEW przypadku Windows wykorzystywany jest (często, ale nie zawsze) typ FILETIME. Tu epoka zaczyna się 1 stycznia 1601 roku, a jeden "tik" to 100 nanosekund. Konwersja między time_t i FILETIME jest opisana między innymi tu: How To Convert a UNIX time_t to a Win32 FILETIME or SYSTEMTIME. Jest ona dość prosta, wystarczy time_t pomnożyć przez 10000000 (różnica w rozdzielczości) i dodać wartość 116444736000000000 (różnica między "epokami"). W drugą stronę najpierw trzeba różnicę między epokami odjąć, a następnie podzielić przez 10000000.
TIMESTAMPW LogParser istnieje typ TIMESTAMP, według dokumentacji: TIMESTAMP values range from January 1, -8192 through December 31, 8191, to an accuracy of one hundred nanoseconds (one ten-thousandth of a millisecond). Z tym, że coś mi się tu nie do końca zgadza. Wartość 0 wyrażona jako TIMESTAMP daje datę 0000-01-01 00:00:00. Data 1 stycznia 1970 roku to 62167219200, co jest podejrzanie małą wartością jak na rozdzielczość 100 nanosekund. Po sprawdzeniu okazuje się, że ta wartość to ilość sekund od 1 stycznia roku 0 do 1 stycznia 1970 roku. Choć prawdopodobnie wszystko się zgadza, bo funkcja TO_TIMESTAMP ma definicję TO_TIMESTAMP ( seconds INTEGER | REAL ), czyli części sekundy reprezentowane są prawdopodobnie po przecinku.
Po co to?Zakładając, że mamy listę "plików" zrzuconą przy pomocy narzędzia ils (SleuthKit), czasy podane w niej są czasami unix time. Próbując "obrabiać" dane przy pomocy LogParser cofamy się mniej więcej do 38 roku (bo 2008 - 1970 = 38). By tę niedogodność usunąć wystarczy dodać do time_t wartość TIMESTAMP dla 1970-01-01, czyli 62167219200. Proste?
I jeszcze przy okazji: How to recognize different types of timestamps from quite a long way away.