std::chrono::floor добавляет 3 часа
using TimePoint = std::chrono::system_clock::time_point;
TimePoint curTime = std::chrono::system_clock::now();
// Здесь время: 2021-03-02 13:37:31.122
using days = std::chrono::duration
<int, std::ratio_multiply<std::ratio<(24 * 60 * 60)>, std::chrono::seconds::period>>;
curTime = std::chrono::floor<days>(curTime);
// Здесь время: 2021-03-02 03:00:00.000
Почему округление вниз происходит до +3 часа а не до нуля 2021-03-02 00:00:00.000 ? Предполагаю, что вмешивается часовой пояс. Каким образом округлить до нуля вне зависимости от часового пояса?
Ничего лучше не придумал, чем обнулить через структуру std::tm
auto timeT = std::chrono::system_clock::to_time_t(curTime);
std::tm tm = *std::localtime(&timeT);
tm.tm_min = 0;
tm.tm_sec = 0;
tm.tm_hour = 0;
curTime = std::chrono::system_clock::from_time_t(std::mktime(&tm));
Ответы (1 шт):
Да, виноват часовой пояс. Нет, часовой пояс в округлении не участвует.
Тип time_point не хранит часовой пояс. Стандарт не указывает какое время там должно быть. Обычно это время по Гринвичу или GMT или UTC или Unix time.
Когда вы вызываете floor - время округляется по Гринвичу.
До сих пор часовой пояс никак не участвовал в процессе. Вы задействуете его когда вызываете std::localtime, который переводит гринвичское время в московское (вы ведь в Москве?) и добавляет три часа: когда в Гринвиче полночь, в Москве три часа ночи.
И так time_point не поддерживает часовые пояса, а вы хотите округлять время с участием текущего часового пояса, в Москве. Раз так, то решение предложенное вами правильное - вы перевели время из Гринвича в Москву и затем округлили.