LINUX.ORG.RU

Что может быть проще времени?

 ,


0

0

Привет всем.

Я как-то давно озадачивался собственной библиотекой даты и времени, чисто из спортивного интереса, и по ходу дела узнал кучу тонкостей, таких как UTC vs GMT vs TAI и др. Забил. Насколько я понял, time_t и struct tm это все учитывают.

Но иногда хочется не научное время, а человеческое, конкретно про время: строго 00:00:00 - 23:59:59 (всегда 86400 секунд), про дату: 0001-01-01 - 9999-12-31, ну и особый февраль. Без DST и TZ (они легко кладутся сверху). Хочется добавлять/вычитать любую компоненту с переносом, а также получать день недели и разницу в днях для дат без времени. Сажать самолеты и жить вечно не планирую.

Есть ли такая простая небольшая библиотека, которая работает с таким вариантом времени? Время кстати не обязательно, оно тривиально. Возможно я чего-то упустил в time_t/tm, если кто-то расскажет, как их отучить от leap-seconds и прочих исторических сдвигов, включая DST. Еще можно тыкнуть в хороший гайд по временной математике.

Календарь григорианский. Спасибо.

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

QDateTime

Чтобы без учета TZ: QDateTime::currentDateTimeUtc ().

Или я совсем не понимаю, чего ты хочешь...

solovey ★★
()
Ответ на: комментарий от solovey

Вообще я не понимаю, что ты имеешь в виду под

не научное время, а человеческое

и чем тебя не устраивает time_t. Может, нужно описать задачу более подробно?

solovey ★★
()
Последнее исправление: solovey (всего исправлений: 1)
Ответ на: комментарий от solovey

Я вот щас гугл перекапываю, похоже меня устраивает time_t time() и double difftime(), поскольку они выкидывают leap-секунды (даже если система их включает), а о struct tm мне переживать похоже не стоит, там внутри все само варится и str[fp]time в курсе.

Странно, несколько лет назад все было ну очень сложно :/

arturpub ★★
() автор топика
Ответ на: комментарий от arturpub

Странно, несколько лет назад все было ну очень сложно :/

и несколько лет назад всё было тоже самое. Этому добру уже хз сколько десятков лет

mashina ★★★★★
()
Ответ на: комментарий от mashina

s/сложно/сложно для меня/ разумеется фикс. В статейке перец писал, что липсекондс все ломают и арифметика нетривиальна. Вот я и вбил себе в голову эту хрень. Мануалы все расставили по местам, sorry for the noise.

arturpub ★★
() автор топика
Ответ на: комментарий от arturpub

арифметика нетривиальна

Так оно и есть. Всё зависит от того, какая именно арифметика Вам нужна. Если нужно просто прибавить N часов/минут/секунд, то всё просто. Если нужно узнать, к примеру, сколько целых суток в определённом интервале времени (с учётом текущей таймзоны и перехода на летнее/зимнее время, конечно), - то уже сложнее. А если нужно определить, сколько времени в одном часовом поясе, когда в другом - 3 часа ночи, да ещё в многопоточной программе, где разным потокам нужны разные часовые пояса, то всё становится совсем нетривиально.

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

сколько целых суток в определённом интервале времени

Разве не (t2-t1)/86400? time_t-то пофигу на зоны, на дст и, как теперь выяснилось, на липы.

сколько времени в одном часовом поясе, когда в другом - 3 часа ночи, да ещё в многопоточной программе, где разным потокам нужны разные часовые пояса

Я так понял _r варианты как раз решают с потоками, а связки вроде timegm/localtime решают по зонам.

Нетривиально — это когда у тебя в потоке секунд внезапно лишняя возникает. Или я что-то недопонимаю?

arturpub ★★
() автор топика
Ответ на: комментарий от arturpub

Разве не (t2-t1)/86400? time_t-то пофигу на зоны, на дст и, как теперь выяснилось, на липы.

time_t вообще на всё пофигу. Это просто счетчик секунд. А человеку обычно - не пофигу. У людей следующие сутки начинаются в 12 часов ночи. И если в прошедшие сутки был переход на летнее/зимнее время, или если вкралась leap-секунда, то эти сутки были длиннее или короче, чем 86400.

Я так понял _r варианты как раз решают с потоками, а связки вроде timegm/localtime решают по зонам.

Они решают эти проблемы только в том случае, когда программа работает фактически в одной временной зоне. Как бонус, доступна ещё работа в зоне UTC. А если нужна третья временная зона?

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

Да, дст я не учел. А про зоны: разве struct tm не рулит зонами? localtime это же способ узнать свою зону, для остального есть gmtime.

arturpub ★★
() автор топика
Ответ на: комментарий от arturpub

Как struct tm может рулить зонами?

Во-первых, в ней нет исчерпывающей информации о зоне. Поля tm_gmtoff и tm_zone этой структуры до сих пор отсутствуют в стандарте POSIX, т.е. полагаться на их наличие нельзя. Но и это - не вся информация о зоне: например, tm_gmtoff показывает смещение только текущего момента относительно UTC, и не показывает, через какое время это смещение изменится.

Во-вторых, для полноценного руления зонами нужен целый набор функций, одной волшебной структуры недостаточно. Этих функций нет в стандартных библиотеках.

localtime это же способ узнать свою зону

Как уже было сказано выше, tm_zone отсутствует в POSIX. Кроме того, от этого поля не так много пользы. Ну узнали Вы зону, а дальше что? Нет ни одной функции, которой можно скормить эту зону в качестве аргумента. Вы можете только каждый раз устанавливать переменную окружения TZ для нужной в данный момент зоны и пользоваться куцым набором функций (localtime() и пр.), при этом забыв про многопоточность.

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

Вы

Я ты.

Суть понял, спасибо, что разжевал.

arturpub ★★
() автор топика

си++ не в счет? Если в счет то boost date_time може все из перечисленного (вроде бы)

а так все расчеты делать в time_t, а дальше gmtime* locatlime*

Что то типа:

time_t now;
struct timeval tv;
gettimeofday(&tv, 0/* или твоя timezone*/);
time_t three_day_ago = tv.tv_sec - 3 * (60 * 60 * 24);
/* еще можно добавить tz и другие вычисления */
localtime_r(...) or gmtime_r(...)

Конечно, все вычисления с 1900 года, но думаю эту проблему тоже можно решить. как-то так, поправьте если не прав

indie
()
Ответ на: комментарий от indie

В плюсы не могу. Я вообще понял, что это мутная замута — считать дни в секундах. Проще укуриться календарной математикой и выкатить отдельную библиотеку по датам, отдельную по времени, и никогда не смешивать дату и время, кроме как в 23:59:59.

Все-таки эти два понятия человеком отдельно воспринимаются, а граничные задачи вроде «сколько прошло со вчера с учетом перевода стрелок» надо решать либо внутри локальной системы координат, либо вообще с ними не связываться. Аэропорты и химпроизводства наверняка живут по атомному времени, а dd.mm.yy hh:mm:ss только на табло используется.

Я просто думал может чо простое уже есть, похоже нет.

arturpub ★★
() автор топика
Ответ на: комментарий от indie

си++ не в счет? Если в счет то boost date_time може все из перечисленного (вроде бы)

Насколько я понимаю, boost date_time не работает с системной базой часовых поясов (tzdata), предлагая вместо этого писать свой файлик базы в другом формате или использовать тот, что идёт в комплекте с boost, т.е. необновляемый. И зачем он такой нужен, этот boost date_time?

Sorcerer ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.