Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: перевод даты в юникс секунды
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
super_puper
думал это очень распространено но потратил 2 часа не нашел кода на си для такой типичной операции.

формат: год месяц день минуты секунды перевести в секунды с 1970 года

желательно проверенный красивый код и наверное без циклов)
NULL
Цитата(super_puper @ Aug 23 2015, 22:57) *
думал это очень распространено но потратил 2 часа не нашел кода на си для такой типичной операции.

формат: год месяц день минуты секунды перевести в секунды с 1970 года

желательно проверенный красивый код и наверное без циклов)


Не оно? mktime
zltigo
QUOTE (super_puper @ Aug 24 2015, 11:57) *
думал это очень распространено но потратил 2 часа не нашел кода на си для такой типичной операции.

Уже и школьная арифметика не по зубам sad.gif, а так-бы потратили 15 минут и написали:
CODE
    
year -= 1970;
leaps = (year+2)/4;
if( !( (year+70) & 3 )&&( month < 3) )
    --leaps;
days  = year*365 + leaps + monthday[month-1] + (day-1);
utime = days*(24*60*60) + (hour+timezone)*(60*60) + min*60 + sec;

Это если на голом месте, а так вообще сишная time() sm.gif
esaulenka
Цитата(super_puper @ Aug 24 2015, 11:57) *
думал это очень распространено но потратил 2 часа не нашел кода на си для такой типичной операции.

Вики
super_puper
Цитата(zltigo @ Aug 25 2015, 01:37) *
Уже и школьная арифметика не по зубам sad.gif, а так-бы потратили 15 минут и написали:
Код
    
year -= 1970;
leaps = (year+2)/4;
if( !( (year+70) & 3 )&&( month < 3) )
    --leaps;
days  = year*365 + leaps + monthday[month-1] + (day-1);
utime = days*(24*60*60) + (hour+timezone)*(60*60) + min*60 + sec;

Это если на голом месте, а так вообще сишная time() sm.gif


както кусок кода не полный помоему -- monthday[month-1]??
esaulenka
Цитата(zltigo @ Aug 24 2015, 22:37) *
Уже и школьная арифметика не по зубам sad.gif, а так-бы потратили 15 минут и написали:


Это называется "велосипедостроение". Бессмысленное и беспощадное.
zltigo
QUOTE (super_puper @ Aug 25 2015, 08:30) *
както кусок кода не полный помоему -- monthday[month-1]??

А Вы даже не догадываетсь, что это такое sad.gif sad.gif sad.gif sad.gif
Это таблица количества дней в месяце. Ну хоть ее из календаря заполнили-бы.
CODE
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334



QUOTE (esaulenka @ Aug 25 2015, 09:17) *
Это называется "велосипедостроение". Бессмысленное и беспощадное.

Как назвать Ваши две реплики я не буду развернуто характиризовать из вежливости. Но,
1) послать, как Вы сделали, в википедию совсем ума не надо.
2) даже помянутая мной сишная функция time() она вообще-то системозависимая - нет операционки с часами реального времени, нет и волшебной функции. Можно, конечно, через две других с заполнением промежуточных структур преобразоваться. Но и самому под голый контроллер написать несложно. И не надо заниматься часами поисками готовых "велосипедных библиотек" соразмерных поискам "чернил для третьего класса". Ну и ЕДИНОЖДЫ написав что-то полезное Вы сможете им пользоваться и в дальнейшем.
jcxz
Цитата(super_puper @ Aug 24 2015, 14:57) *
думал это очень распространено но потратил 2 часа не нашел кода на си для такой типичной операции.

Для операции "/=" тоже примеры кода в инете ищете?

Функция Encode() преобразует дату в секунды с любым базовым годом, не обязательно 1970:
CODE
#define BASE_YEAR 2011 //базовый год Службы времени
#define N_YEARS 136 //кол-во лет, охватываемых Службой времени
//(служба времени работоспособна от BASE_YEAR года до (BASE_YEAR+N_YEARS-1) года включительно)

u8 const month2days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

struct DateTime {
u8 seconds, minutes, hours, date, month, day;
u16 year;
u32 Encode() const;
int Set(u32);
};

//кол-во дней перед началом года 'y'
#define daysBeforeYear(y) ((u32)((y) - 1) * 365 + \
(u32)((y) - 1) / 4 - (u32)((y) - 1) / 100 + (u32)((y) - 1) / 400)

//кол-во дней, охватываемых Службой времени (макс. диапазон времени в днях)
#define N_DAYS (daysBeforeYear(BASE_YEAR+N_YEARS) - daysBeforeYear(BASE_YEAR))

//возвращает true - если год невисокосный, false - иначе
u32 isNoVisokos(u32 year)
{
u32 c, i;
if (!(c = (i = year) & 3)) if ((i /= 100) * 100 == year) c = i & 3;
return c;
}

//преобразует DateTime в кол-во секунд от начала BASE_YEAR
//при ошибке возвращает ~0
//член day - игнорируется
u32 DateTime::Encode() const
{
u32 cc, i, j;
u8 const *s;
if ((cc = year) - BASE_YEAR >= N_YEARS) return ~0;
j = daysBeforeYear(cc) - daysBeforeYear(BASE_YEAR);
if ((i = month) > 11) return ~0;
s = month2days;
while ((s32)--i >= 0) j += *s++;
i = *s;
if (!isNoVisokos(cc)) {
if ((uint)month > 1) j++;
if (month == 1) i++;
}
if (date >= i) return ~0;
j = (date + j) * 24;
if ((uint)hours > 23) return ~0;
j = (hours + j) * 60;
if ((uint)minutes > 59) return ~0;
j = (minutes + j) * 60;
if ((uint)seconds > 59) return ~0;
return seconds + j;
}
esaulenka
Цитата(zltigo @ Aug 25 2015, 09:38) *
1) послать, как Вы сделали, в википедию совсем ума не надо.

Тем не менее, там есть готовый кусок кода. Работающий.

А написать своё, тесты продумать-сделать-прогнать... У меня часа два займёт. Можно только восхищаться человеком, производительность которого на порядок выше.

Я сам не большой любитель супербиблиотек со встроенной кофеваркой.
Но тут задача - стандартнее придумать сложно, надо брать готовое.
zltigo
QUOTE (esaulenka @ Aug 25 2015, 10:49) *
Тем не менее, там есть готовый кусок кода. Работающий.

Да, не заметил под спойлером sad.gif. Хотя, конечно, "кусок кода" еще тот по замороченности на ровном месте, да и писанный под определенное окружение.
Тот кусок, котрый я привел, писал, не поверите sm.gif - в доинтернетовскую эпоху - CCCР был, а интернета не было sm.gif. Просто взял и написал - задача ведь банально-арифметическая. И с тех пор беру его у себя-же и не ищу кто-бы его "изобрел".
adnega
Цитата(super_puper @ Aug 24 2015, 11:57) *
думал это очень распространено но потратил 2 часа не нашел кода на си для такой типичной операции.

формат: год месяц день минуты секунды перевести в секунды с 1970 года

желательно проверенный красивый код и наверное без циклов)

Перевод туда-сюда. Правда, начало эпохи 01.01.2000 00:00:00.
Коректно работет до 2100 года. Время добавить самостоятельно)
CODE
//-----------------------------------------------------------------------------
// void int_to_date(const DWORD jd, DWORD *y, DWORD *m, DWORD *d)
//-----------------------------------------------------------------------------
void int_to_date(const DWORD jd, DWORD *y, DWORD *m, DWORD *d)
{
int aa, bb, cc, dd, ee, mm, xx;

aa = jd + 2483589;
bb = (aa * 4 + 3) / 146097;
cc = aa - ((146097 * bb) >> 2);
dd = (4 * cc + 3) / 1461;
ee = cc - ((1461 * dd) >> 2);
mm = ((5 * ee + 2) * 13707) >> 21;

*d = ee - ((16043274 * mm + 209716) >> 19) + 1;
*m = mm + 3 - 12 * ((mm * 27) >> 8);
*y = 100 * bb + dd - 4800 + ((mm * 27) >> 8);
}

//-----------------------------------------------------------------------------
// DWORD date_to_int(DWORD y, DWORD m, const DWORD d)
//-----------------------------------------------------------------------------
DWORD date_to_int(DWORD y, DWORD m, const DWORD d)
{
if(m < 3)
{
m += 12;
y -= 1;
}
return ((y * 1461) >> 2) + ((m * 306 + 7) / 10) + d - 730533;
}
jcxz
Цитата(adnega @ Aug 25 2015, 14:44) *
Перевод туда-сюда. Правда, начало эпохи 01.01.2000 00:00:00.
Коректно работет до 2100 года. Время добавить самостоятельно)

У меня круче rolleyes.gif
У Вас не хватает проверок на валидность заданной даты (чтобы не было 31 февраля).
super_puper
мне кажется не надо стеснятся казалось бы банальных вопросов, всем спасибо за коды если есть еще кидайте все варианты интересны)
adnega
Цитата(jcxz @ Aug 26 2015, 07:33) *
У меня круче rolleyes.gif
У Вас не хватает проверок на валидность заданной даты (чтобы не было 31 февраля).

31 февраля соответствует 03 марта.
Валидность специально не делал, чтоб можно было дни и месяцы просто добавлять/убавлять.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.