Перейти к содержанию
    

перевод даты в юникс секунды

думал это очень распространено но потратил 2 часа не нашел кода на си для такой типичной операции.

 

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

 

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

Изменено пользователем super_puper

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

думал это очень распространено но потратил 2 часа не нашел кода на си для такой типичной операции.

 

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

 

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

 

Не оно? mktime

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

думал это очень распространено но потратил 2 часа не нашел кода на си для такой типичной операции.

Уже и школьная арифметика не по зубам :(, а так-бы потратили 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() :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

думал это очень распространено но потратил 2 часа не нашел кода на си для такой типичной операции.

Вики

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уже и школьная арифметика не по зубам :(, а так-бы потратили 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() :)

 

както кусок кода не полный помоему -- monthday[month-1]??

Изменено пользователем super_puper

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уже и школьная арифметика не по зубам :(, а так-бы потратили 15 минут и написали:

 

Это называется "велосипедостроение". Бессмысленное и беспощадное.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

както кусок кода не полный помоему -- monthday[month-1]??

А Вы даже не догадываетсь, что это такое :( :( :( :(

Это таблица количества дней в месяце. Ну хоть ее из календаря заполнили-бы.

0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334

 

 

Это называется "велосипедостроение". Бессмысленное и беспощадное.

Как назвать Ваши две реплики я не буду развернуто характиризовать из вежливости. Но,

1) послать, как Вы сделали, в википедию совсем ума не надо.

2) даже помянутая мной сишная функция time() она вообще-то системозависимая - нет операционки с часами реального времени, нет и волшебной функции. Можно, конечно, через две других с заполнением промежуточных структур преобразоваться. Но и самому под голый контроллер написать несложно. И не надо заниматься часами поисками готовых "велосипедных библиотек" соразмерных поискам "чернил для третьего класса". Ну и ЕДИНОЖДЫ написав что-то полезное Вы сможете им пользоваться и в дальнейшем.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

думал это очень распространено но потратил 2 часа не нашел кода на си для такой типичной операции.

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

 

Функция Encode() преобразует дату в секунды с любым базовым годом, не обязательно 1970:

#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;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) послать, как Вы сделали, в википедию совсем ума не надо.

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

 

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

 

Я сам не большой любитель супербиблиотек со встроенной кофеваркой.

Но тут задача - стандартнее придумать сложно, надо брать готовое.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Да, не заметил под спойлером :(. Хотя, конечно, "кусок кода" еще тот по замороченности на ровном месте, да и писанный под определенное окружение.

Тот кусок, котрый я привел, писал, не поверите :) - в доинтернетовскую эпоху - CCCР был, а интернета не было :). Просто взял и написал - задача ведь банально-арифметическая. И с тех пор беру его у себя-же и не ищу кто-бы его "изобрел".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

думал это очень распространено но потратил 2 часа не нашел кода на си для такой типичной операции.

 

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

 

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

Перевод туда-сюда. Правда, начало эпохи 01.01.2000 00:00:00.

Коректно работет до 2100 года. Время добавить самостоятельно)

//-----------------------------------------------------------------------------
//	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;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Перевод туда-сюда. Правда, начало эпохи 01.01.2000 00:00:00.

Коректно работет до 2100 года. Время добавить самостоятельно)

У меня круче :rolleyes:

У Вас не хватает проверок на валидность заданной даты (чтобы не было 31 февраля).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

мне кажется не надо стеснятся казалось бы банальных вопросов, всем спасибо за коды если есть еще кидайте все варианты интересны)

Изменено пользователем super_puper

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня круче :rolleyes:

У Вас не хватает проверок на валидность заданной даты (чтобы не было 31 февраля).

31 февраля соответствует 03 марта.

Валидность специально не делал, чтоб можно было дни и месяцы просто добавлять/убавлять.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...