Насколько безопасно предполагать, что time_t в секундах?

Я делаю много вычислений со временем, строю объекты времени относительно других объектов времени, добавляя секунды. Код должен работать на встроенных устройствах и серверах. Большинство документов говорят о time_t что это какой-то арифметический тип, хранящий обычно время с эпохи. Насколько безопасно предполагать, что time_t хранить количество секунд, так как что-то? Если мы можем предположить, что мы можем просто использовать сложение и вычитание, а не localtime, mktime а также difftime,

До сих пор я решил проблему с помощью constexpr bool time_tUsesSeconds, обозначая, можно ли считать, что time_t использует секунды. Если это непереносимо предположить time_t в секундах, есть ли способ автоматически инициализировать эту константу?

time_t timeByAddingSeconds(time_t theTime, int timeIntervalSeconds) {
if (Time_tUsesSeconds){
return theTime + timeIntervalSeconds;
} else {
tm timeComponents = *localtime(&theTime);
timeComponents.tm_sec += timeIntervalSeconds;
return mktime(&timeComponents);
}
}

6

Решение

Факт, что это в секундах, установлен Спецификация POSIX, так что, если вы программируете для POSIX-совместимых сред, вы можете положиться на это.

Стандарт C ++ также гласит, что time_t должен быть арифметическим типом.

В любом случае, система синхронизации Unix (вторая после эпохи) будет переполнена в 2038 году. Таким образом, весьма вероятно, что до этой даты реализации C ++ переключатся на другие не-int типы данных (либо 64-битные int, либо более сложные типы данных). ). В любом случае, переключение на 64b int нарушит двоичную совместимость с предыдущим кодом (поскольку для этого требуются большие переменные), и все должно быть перекомпилировано. Использование непрозрачных дескрипторов 32b не нарушит бинарную совместимость, вы можете изменить базовую библиотеку, и все по-прежнему работает, но time_t не будет больше времени в секундах, это будет индекс для массива раз в секундах. По этой причине предлагается использовать функции, которые вы упомянули, для манипулирования значениями time_t, и не предполагать, что time_t,

8

Другие решения

Вместо того чтобы определить, time_t в секундах, так как time_t является арифметическим типом, вы можете вместо этого вычислить time_t значение, которое представляет одну секунду, и работать с этим. Этот ответ я написал раньше объясняет метод и имеет некоторые предостережения, вот пример кода (bad_time() класс пользовательских исключений, здесь):

time_t get_sec_diff() {
std::tm datum_day;
datum_day.tm_sec = 0;
datum_day.tm_min = 0;
datum_day.tm_hour = 12;
datum_day.tm_mday = 2;
datum_day.tm_mon = 0;
datum_day.tm_year = 30;
datum_day.tm_isdst = -1;

const time_t datum_time = mktime(&datum_day);
if ( datum_time == -1 ) {
throw bad_time();
}

datum_day.tm_sec += 1;
const time_t next_sec_time = mktime(&datum_day);
if ( next_sec_time == -1 ) {
throw bad_time();
}

return (next_sec_time - datum_time);
}

Вы можете вызвать функцию один раз и сохранить значение в const, а затем просто использовать его всякий раз, когда вам нужно time_t второй. Я не думаю, что это будет работать в constexpr хоть.

2

Мои два цента: на Windows это в секундах через некоторое время но время, необходимое для перехода к следующей секунде, обычно составляет 18 * 54,925 мс, а иногда 19 * 54,925. Причина этого объясняется в эта почта.

0

В стандарте C или стандарте C ++ нет требований к единицам, которые time_t представляет собой. Для работы с секундами переносимо нужно использовать struct tm, Вы можете конвертировать между time_t а также struct tm с mktime а также localtime,

0

(Отвечая на собственный вопрос)

Один ответ предполагает, что пока кто-то использует posix, time_t в секундах и арифметика на time_t должно сработать.

Второй ответ вычисляет time_t в секунду и использует его как фактор при выполнении арифметики. Но есть еще некоторые предположения о time_t сделал.

В конце концов я решил, что переносимость важнее, я не хочу, чтобы мой код молчал на каком-то встроенном устройстве. Поэтому я использовал третий способ. Это включает в себя сохранение целого числа, обозначающего время с момента запуска программы. То есть Я определяю

 const static time_t time0 = time(nullptr);
static tm time0Components = *localtime(&time0);

Все значения времени, используемые в программе, являются целыми числами, обозначающими разницу во времени с time0, Идти от time_t до этой дельты секунды, я использую difftime, Вернуться к time_tЯ использую что-то вроде этого:

time_t getTime_t(int timeDeltaSeconds) {
tm components = time0Components;
components.tm_sec += timeDeltaSeconds;
return mktime(&components);
}

Такой подход позволяет делать такие операции, как +,- дешево, но возвращаюсь time_t дорогой. Обратите внимание, что значения дельта времени имеют смысл только для текущего запуска программы. Также обратите внимание, что time0Components должен обновляться при изменении часового пояса.

0
По вопросам рекламы [email protected]