Текущее время и дата в C ++ 20 дней - PullRequest
4 голосов
/ 13 апреля 2020

Я быстро прочитал справочник C ++ о новых классах хроно, но я нашел их немного сложными.

Итак, вопрос в том, как переписать этот код на C ++ 20, чтобы получить год , месяц, день, час, минута, секунда?

Есть ли изменения? Я спрашиваю из-за этой незначительной проблемы с std::localtime: это небезопасно. tm будет уничтожено после следующего вызова std::localtime.

std::time_t t = std::time(nullptr);
std::tm *tm = std::localtime(&t);
int year = tm->tm_year + 1900;
int month = tm->tm_mon + 1;
int day = tm->tm_mday;
int hour = tm->tm_hour;
int minute = tm->tm_min;
int second = tm->tm_sec;

1 Ответ

4 голосов
/ 13 апреля 2020
#include <chrono>

int
main()
{
    using namespace std::chrono;

    // Get a local time_point with system_clock::duration precision
    auto now = zoned_time{current_zone(), system_clock::now()}.get_local_time();

    // Get a local time_point with days precision
    auto ld = floor<days>(now);

    // Convert local days-precision time_point to a local {y, m, d} calendar
    year_month_day ymd{ld};

    // Split time since local midnight into {h, m, s, subseconds}
    hh_mm_ss hms{now - ld};

    // This part not recommended.  Stay within the chrono type system.
    int year{ymd.year()};
    int month = unsigned{ymd.month()};
    int day = unsigned{ymd.day()};
    int hour = hms.hours().count();
    int minute = hms.minutes().count();
    int second = hms.seconds().count();
}

Я пытался объяснить, что каждая строка кода делает с комментарием. Я с удовольствием уточню, если что-то не понятно.

Это все потокобезопасно.

Дополнительная информация:

Другое и, возможно, даже больше краткий способ вычисления now:

auto now = current_zone()->to_local(system_clock::now());

Это приводит к тому же типу и значению для now.

Я использовал zoned_time выше, потому что это так (в общем ) абстракция более высокого уровня, чем прямой вызов функций-членов time_zone. В обоих примерах тип now представляет собой простое std::chrono::time_point, которое смещено от system_clock::time_point смещением UT C, связанным с time_zone в данный момент времени.

В отличие от zoned_time несет гораздо больше информации. Например, он знает о:

  • Имя time_zone.
  • Сокращение для time_zone на данный момент времени.
  • UT C смещение time_zone в этот момент времени, и впоследствии может производить как местное время, так и UT C эквивалентное время.
  • Допустимый диапазон пары смещение / сокращение.

Поэтому zoned_time гораздо более гибок для заданий, таких как форматирование, поскольку он может отображать аббревиатуру и / или смещение UT C. И zoned_time также может быть проще использовать для определения эквивалентного времени в других часовых поясах.

Тем не менее, вся эта дополнительная информация на самом деле не используется в этом простом примере, и именно поэтому я Я предлагаю альтернативный вызов функции-члена to_local() для time_zone напрямую.

Для простого случая нахождения местного времени оба метода имеют идентичное поведение и производительность, поэтому все сводится к вопросу удобочитаемости при выборе предпочтительного подхода.

...