Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > упаковка даты-времени и развертва в таймштамп


Автор: IgnisFatuus 21.7.2015, 13:46
Доброго дня! Занимаюсь тут изучением библиотеки FatFS и наткнулся на проблему - дата и время там хранятся в своем формате, есть double word переменная 16 бит даты и 16 бит со временем.

Код

bit31:25
Year origin from the 1980 (0..127)
bit24:21
Month (1..12)
bit20:16
Day of the month(1..31)
bit15:11
Hour (0..23)
bit10:5
Minute (0..59)
bit4:0
Second / 2 (0..29)


Накидал тут простенькую программку, чтобы глянуть - а правильно будет время обрабатываться потом - вот что получилось :

Код

#include <iostream>
#include <string.h>

typedef unsigned long    DWORD;
typedef unsigned short    WORD;

int main() {


    time_t t = time(NULL);
    struct tm tm_ = *localtime(&t);
    WORD date;
    WORD time;

    DWORD variable = ((DWORD)(tm_.tm_year - 80) << 25)
                   | (((DWORD)tm_.tm_mon + 1) << 21)
                   | ((DWORD)tm_.tm_mday << 16)
                   | ((DWORD)tm_.tm_hour << 11)
                   | ((DWORD)tm_.tm_min << 5)
                   | ((DWORD)((tm_.tm_sec >> 1)));

    memcpy(&time, &variable, sizeof(time));

    date = (variable>> 16);

    std::cout << "time = " << time << std::endl;
    std::cout << "date = " << date << std::endl;

    tm last_mod;
    last_mod.tm_year = (((date & 0xFE00) >> 9) + 80);
    last_mod.tm_mon = ((date & 0x1E0) >> 5);
    if(last_mod.tm_mon != 0) last_mod.tm_mon -=1;
    last_mod.tm_mday = ((date & 0x1F));

    int result_s = (((int)time & (int)0xF800) >> 11);
    last_mod.tm_hour = (unsigned)result_s;

    last_mod.tm_min = ((time & 0x7E0) >> 5);
    last_mod.tm_sec = ((time & 0x1F));


    std::cout << "create TS   " << mktime(&tm_) << std::endl;
    std::cout << "restored TS " <<   mktime(&last_mod) << std::endl;
    return 0;
}


вывод -
 time = 27725
date = 18165
create TS    1437474866
restored TS 1437471253



как видно - ТS не совпадают. Что я делаю не так?

Автор: feodorv 21.7.2015, 21:18
Цитата(IgnisFatuus @  21.7.2015,  13:46 Найти цитируемый пост)
   memcpy(&time, &variable, sizeof(time));

Почему не просто:
Код
time = (WORD) variable;
???


Цитата(IgnisFatuus @  21.7.2015,  13:46 Найти цитируемый пост)
    last_mod.tm_sec = ((time & 0x1F));

Секунды должны быть умножены на два. Или << 1.


Цитата(IgnisFatuus @  21.7.2015,  13:46 Найти цитируемый пост)
Что я делаю не так? 

Где инициализация поля tm_isdst? Если отбросить недоразумение с секундами, то у Вас отличие "create TS" от "restored TS" на один час (3600 секунд).

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