C ++ Время без даты? - PullRequest
       4

C ++ Время без даты?

1 голос
/ 23 июня 2019

Каков оптимальный способ работы с точками времени без дат в C ++?

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

Мне нужно выполнить две задачи:

  1. Сохранить данные времени, представленные метками времени.
  2. Рассчитать разницу между временами.

Мне известно, что в C ++ есть библиотеки со структурами данных времени. Некоторые из этих структур данных включают информацию о датах. Если возможно, я не хочу использовать такие структуры данных, потому что мои данные не включают даты. Мне нужна функциональность, аналогичная функциональности для временных структур данных в

  • Boost.Date_Time
  • хроно
  • CTime

но без хранения даты или чего-либо еще, кроме 24-часового военного времени (явного или неявного).

Мне нужны объекты точки времени, которые не хранят никакой информации о дате или о чем-либо кроме 24-часового военного времени. Я хочу

  1. Приведите мои метки времени к этим объектам.

, затем

  1. Найти различия между результирующими временными точками (длительности между временными точками).

Каков наилучший способ сделать это?

Мое идеальное решение включает в себя уже существующую стандартную или ускоренную библиотеку и позволяет избежать хранения любой информации о дате, часовом поясе или о чем-либо, кроме 24-часового военного времени. Возможно, я упустил из виду, что моя потребность может быть удовлетворена одной из библиотек, которые я уже упоминал (то есть Boost.Date_Time, chrono или ctime).

1 Ответ

1 голос
/ 23 июня 2019

Одна идея состоит в том, чтобы создать пользовательские 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чрезмерно ограничительный и попытается уменьшить их до того, что действительно требуется в будущем стандарте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...