Я сделал две функции, которые должны вычислять начальную временную метку дня (т.е. в 00:00:00 дня) и час (начиная с 1 и до 24) данной временной метки эпохи.
#include <cstdint>
#include <ctime>
const uint8_t FIRST_HOUR = 0x01; // 01, 02, ..., 24
const uint32_t SECS_PER_HOUR = 3600; // 3600 secs per hour
uint32_t CalcDaiBaseTimestamp(uint32_t in_ts) {
time_t ts = in_ts;
struct tm timeinfo = *localtime(&ts);
timeinfo.tm_hour = 0;
timeinfo.tm_min = 0;
timeinfo.tm_sec = 0;
time_t tmp_base_ts = mktime(&timeinfo);
return (uint32_t)tmp_base_ts;
}
void CalcDaiBaseTimestampAndHour(uint32_t in_ts,
uint32_t& base_ts,
uint8_t& hour_nth) {
base_ts = CalcDaiBaseTimestamp(in_ts);
hour_nth = (in_ts - base_ts) / SECS_PER_HOUR + FIRST_HOUR;
}
CalcDaiBaseTimestampAndHour
вызывается из нескольких потоков.
Код скомпилирован с g++ (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4
, а программа работает на Ubuntu 14.04 x64
.
Большую часть времени моя программа работает хорошо, но я иногда наблюдал некоторые «странные» результаты, как показано ниже:
(timestamp: 1554459477.500) -> (base: 1553990400, hour_nth: 131)
Пока правильный результат должен быть:
(timestamp: 1554459477.500) -> (base: 1554422400 / hour_nth: 11)
Потому что:
1554459477.500 = 2019-04-05 10:17:57.500
base_ts = 2019-04-05 00:00:00 = 1554422400
hour_nth = 11
Так как проблема иногда возникает, поэтому я предполагаю, что причиной может быть поточная безопасность некоторых ctime
связанных функций.
Что может вызвать "странные" результаты? Пожалуйста, помогите мне решить эту проблему! Если на самом деле причина в поточной безопасности функций, связанных с ctime
, то как я могу обойти эту проблему (например, с помощью некоторой стандартной библиотеки C ++ 11)?