Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Определить формат представления даты и времени

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки

Открыть новую тему     Написать ответ в эту тему

graf0man

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Пожалуйста помогите определить формат представления даты и времени.
В бинарнике от Микрософт дата-время занимают 8 байт.
Привожу примеры (как хранятся в файле):
 
00 5E 4D 8F DD 88 C6 01
00 2C 79 5E 74 1C C4 01
00 28 51 48 01 FD C5 01
и т.п.
 
Видимо в 01Ch закодировано начало года 200..
 
Интересует название алгоритма и способ декодирования (вручную).

Всего записей: 10 | Зарегистр. 01-01-2006 | Отправлено: 02:00 19-06-2006
Mickey_from_nsk

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
graf0man
Склонен считать, что тут длинное целое как в UNIX - там считаются секунды с (если не ошибаюсь) 01/01/1970. Не думаю, что тут структуру замутили.

Всего записей: 636 | Зарегистр. 21-10-2002 | Отправлено: 09:25 19-06-2006
graf0man

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Mickey_from_nsk
 
а я поделил - у меня получилось около 4 миллионов лет. что-то многовато вроде...

Всего записей: 10 | Зарегистр. 01-01-2006 | Отправлено: 09:43 19-06-2006
Mickey_from_nsk

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
graf0man
А ты какими функциями пользуешься? Если этот тип - time_t, значит смотри в каком формате все сохраняется. Наверно тут еще байты надо в нужном формате переставить.

Всего записей: 636 | Зарегистр. 21-10-2002 | Отправлено: 10:02 19-06-2006
graf0man

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
<b>Mickey_from_nsk</b>
 
функциями никакими не пользуюсь - просто подсчитал, сколько секунд в году и разделил хранящееся число на число секунд.
 
поскольку данные хранятся в бинарном файле, то логично предположить, что байты лежат в обратном порядке. т.е. реальное 16-ричное число имеет вид
01C688DD8F4D5E00
 
на это также подталкивает то, что часть 01C у них у всех одинаковая.
 

Всего записей: 10 | Зарегистр. 01-01-2006 | Отправлено: 11:13 19-06-2006
Mickey_from_nsk

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
graf0man
Покопался в MSDN. Наверно дата хранится в микрософтовском формате:

Код:
 
typedef struct _FILETIME {  DWORD dwLowDateTime;  DWORD dwHighDateTime;
} FILETIME, *PFILETIME;
 

Ща поколдую, попробую перевести тебе эти цифирки
 
 
Добавлено:
Вот чего наколдовал:
00 5E 4D 8F DD 88 C6 01 = 2006/06/05 20:21:00
00 2C 79 5E 74 1C C4 01 = 2004/04/07 07:46:00
00 28 51 48 01 FD C5 01 = 2005/12/09 20:44:00
 
Собсно код:

Код:
 
#include <Windows.h>
#include <stdio.h>
 
void main()
{
    ULARGE_INTEGER ui;
    FILETIME ft;
    SYSTEMTIME st;
 
    ui.LowPart = 0x48512800;
    ui.HighPart = 0x01c5fd01;
    ft.dwLowDateTime = ui.LowPart;
    ft.dwHighDateTime = ui.HighPart;
 
    FileTimeToSystemTime(&ft, &st);
     
    printf("%02d/%02d/%02d %02d:%02d:%02d",  
            st.wYear, st.wMonth, st.wDay,
            st.wHour, st.wMinute, st.wSecond);
}
 

 
И из MSDN:

Цитата:
The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).
 

Всего записей: 636 | Зарегистр. 21-10-2002 | Отправлено: 12:51 19-06-2006 | Исправлено: Mickey_from_nsk, 13:14 19-06-2006
graf0man

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Mickey_from_nsk
большое спасибо за подсказку! все стало проясняться. теперь осталось придумать, как сделать декодирование в паскале...
 
написал в Virtual Pascal так:
var co: Comp;
...
tts:=MSecsToTimeStamp(co);
tdt:=TimeStampToDateTime(tts);
write(FormatDateTime('d/m/yyyy hh:nn',tdt));
 
но выводит упорно какие-то 55-тысячные года
 

Всего записей: 10 | Зарегистр. 01-01-2006 | Отправлено: 20:00 19-06-2006 | Исправлено: graf0man, 20:59 19-06-2006
Mickey_from_nsk

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
graf0man
Не знаю как паскаль там с датами работает, на С все просто. Надо только перейти к секундам и сдвинуть точку отсчета на 1970 г.
Просто если все вручную писать - замучаешься отсчитывать даты.
А вообще можно сделать следующее.
Я тебе написал несколько реперов. Вычитай даты из них и получишь смещения в сотнях наносекунд. Далее - все просто.

Всего записей: 636 | Зарегистр. 21-10-2002 | Отправлено: 07:17 20-06-2006
FireZone

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
graf0man
Код:
uses .. windows, ...  
 
function Int64ToDateTime(i: Int64): TDateTime;
var
  st: _SYSTEMTIME;
begin
  FileTimeToSystemTime(_FILETIME(i), st);
  result := SystemTimeToDateTime(st)
end;
 
...
  dt := Int64ToDateTime( $01c5fd0148512800 );
  ShowMessage(FormatDateTime('d/m/yyyy hh:nn',dt))
...

Всего записей: 293 | Зарегистр. 28-01-2004 | Отправлено: 08:02 20-06-2006
graf0man

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
FireZone
приведенный пример в Virtual Pascal работать не будет - тот не знает Int64, ну и _SYSTEMTIME _FILETIME до кучи

Всего записей: 10 | Зарегистр. 01-01-2006 | Отправлено: 08:57 20-06-2006
Mickey_from_nsk

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
graf0man
Мдаа, тогда тяжелее. Надо тогда самому написать 64 разрядную арифметику. Без этого вообще сложно. Можно, конечно, попробовать через что-то типа decimal (если оно есть) или какими нибудь супермного байтовыми вещественными (типа long double в С).

Всего записей: 636 | Зарегистр. 21-10-2002 | Отправлено: 09:30 20-06-2006
graf0man

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Mickey_from_nsk
там есть Comp, который 64 бита как раз вмещает.

Всего записей: 10 | Зарегистр. 01-01-2006 | Отправлено: 09:50 20-06-2006
FireZone

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
graf0manБез извратов. Всё оказалось проще.
Код:
function CompToDateTime(c: Comp): TDateTime;
var
  diff: TDateTime;
begin
  diff := StrToDate('01.01.1601');
  result := c/10000/MSecsPerDay + diff;
end;
Поправку diff лучше сохранить где-нибудь как константу.

Всего записей: 293 | Зарегистр. 28-01-2004 | Отправлено: 10:16 20-06-2006
graf0man

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
FireZone
премного благодарен! работает!
правда пришлось добавить еще +StrToTime('04:00'), а то получалась разница на 4 часа по сравнению с реальностью

Всего записей: 10 | Зарегистр. 01-01-2006 | Отправлено: 10:59 20-06-2006
Открыть новую тему     Написать ответ в эту тему

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Определить формат представления даты и времени


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru