Одна идея состоит в том, чтобы создать пользовательские chrono
часы, возможно, названные time_of_day_clock
, а затем создать из них семейство chrono::time_point
с.Или, может быть, вам нужно только seconds
точное время (вы не знали об этом).Вот все, что нужно для создания seconds
-точности time_point
на таких часах:
struct time_of_day_clock {};
using time_of_day = std::chrono::time_point<time_of_day_clock,
std::chrono::seconds>;
Теперь вы можете создать пару вспомогательных функций для приведения между std::string
и time_of_day
:
// Assume t is of the form HH:MM:SS
time_of_day
to_time_of_day(const std::string& t)
{
using namespace std::chrono;
auto parse = [&t](auto i) -> int
{
return (t[i]-'0')*10 + (t[i+1]-'0');
};
hours h{parse(0)};
minutes m{parse(3)};
seconds s{parse(6)};
return time_of_day{h+m+s};
}
// Format to HH:MM:SS
std::string
to_string(const time_of_day& t)
{
using namespace std;
using namespace std::chrono;
auto s = t.time_since_epoch();
assert(s >= 0s);
assert(s < 86400s);
auto h = duration_cast<hours>(s);
s -= h;
auto m = duration_cast<minutes>(s);
s -= m;
string r = "00:00:00";
auto print = [&r](auto i, auto j)
{
for (++j; i != 0; i /= 10, --j)
r[j] = i % 10 + '0';
};
print(h.count(), 0);
print(m.count(), 3);
print(s.count(), 6);
return r;
}
Теперь у вас есть все инструменты, чтобы сделать что-то вроде этого:
int
main()
{
auto t1 = to_time_of_day("17:15:23");
auto t2 = to_time_of_day("07:14:06");
std::cout << "t1 = " << to_string(t1) << '\n';
std::cout << "t2 = " << to_string(t2) << '\n';
auto d = t1 - t2;
std::cout << d.count() << "s\n";
auto t3 = t2 + d;
std::cout << "t3 = " << to_string(t3) << '\n';
}
Вывод:
t1 = 17:15:23
t2 = 07:14:06
36077s
t3 = 17:15:23
Это дает вам безопасность типов: время дня не будет перепутано с длительностями , но они будут взаимодействовать с рациональной алгеброй.
Добавьте столько проверки ошибок к вышеприведенномукак требуется / требуется для вашего приложения.
В приведенном выше плане есть один небольшой сбой: языковые адвокаты могут жаловаться, что все дело в неопределенном поведении, потому что time_of_day_clock
не соответствует требованиям к хронографическим часам.
Реальность такова, что все будет работать, если вы не попытаетесь вызвать now()
на time_of_day_clock
или использовать time_of_day
с алгоритмом, который пытается это сделать (или пытается получить доступ к вложенному типу time_of_day_clock
).И если вы случайно сделаете это, результатом будет ошибка времени компиляции, а не ошибка времени выполнения и не неопределенное поведение.
Я рассматриваю требования к параметру Clock
шаблона time_point
чрезмерно ограничительный и попытается уменьшить их до того, что действительно требуется в будущем стандарте.