Я рассчитал день, день месяца и год, а также секунды, минуты и часы, используя std::chrono::local_days, мне просто нужно получить день недели. Код, который я использую, был предоставлен Говардом Хиннантом в ответе здесь, комментарии принадлежат мне:
auto tp = std::chrono::system_clock::now();
static auto const tz = std::chrono::current_zone();
static auto info = tz->get_info(tp); // CACHE THE TIMEZONE INFO
if (tp >= info.end) // APPARENTLY THE TIME ZONE INFO CAN CHANGE UP TO TWICE A YEAR
info = tz->get_info(tp);
auto tpl = std::chrono::local_days{} + (tp + info.offset - std::chrono::sys_days{});
auto tpd = floor<std::chrono::days>(tpl);
std::chrono::year_month_day ymd{ tpd };
std::chrono::hh_mm_ss hms{ tpl - tpd };
На данный момент у меня есть то, о чем я упоминал выше: как мне получить день недели с как можно меньшим количеством лишних вызовов?
Вы можете получить день недели, используя структуру std::tm:
const auto now = std::chrono::system_clock::now();
const auto in_time_t = std::chrono::system_clock::to_time_t(now);
std::stringstream output_stream;
struct tm time_info;
localtime_s(&time_info, &in_time_t);
std::cout << time_info.tm_wday << std::endl;
Я бы подумал просто заменить код, который у вас есть в вашем вопросе, на этот, поскольку структуру tm можно использовать для легкого получения дня года.
time_info.tm_yday
Или дневное время
time_info.tm_sec
time_info.tm_min
time_info.tm_hour
Вы можете преобразовать дни в year_month_weekday
, а затем получить часть weekday
.
std::chrono::year_month_weekday ymwd{ tpd };
std::chrono::weekday wd = ymwd.weekday();
Чтобы получить индекс от wd
, вы можете вызвать wd.c_encoding()
или wd.iso_encoding()
, в зависимости от того, хотите ли вы, чтобы воскресенье было представлено как 0
или 7
.
Значит, год_месяц_день и год_месяц_неделя нужно вызывать отдельно?
@Zebrafish Вы также можете конвертировать year_month_day
в year_month_weekday
: std::chrono::year_month_weekday ymwd{ ymd };
.
Что это за конструктор? Я не вижу такого конструктора для типа год_месяц_неделя, я имею в виду конструктор, который принимает год_месяц_день en.cppreference.com/w/cpp/chrono/year_month_weekday/…
Явное преобразование year_month_day
в year_month_weekday
работает путем неявного преобразования из year_month_day
в sys_days
, а затем из sys_days
в year_month_weekday
. Действительно, именно этот механизм позволяет любым двум календарным системам (поставляемым хромом или написанным пользователем) явно конвертировать друг в друга, если обе календарные системы обеспечивают неявные преобразования в sys_days
и обратно.
Остальные ответы дают правильный ответ, но вот наиболее эффективный метод:
std::chrono::weekday wd{tpd};
Просто преобразуйте local_days
в weekday
. Это даст вам местный день недели (потому что вы перешли с local_days
).
Все, что делает это преобразование, — это выполняет этот низкоуровневый алгоритм:
return static_cast<unsigned>(tpd >= -4 ? (tpd +4) % 7 : (tpd +5) % 7 + 6);
так что это примерно настолько эффективно, насколько это возможно.
Другие комментарии:
// ВЕРОЯТНО, ИНФОРМАЦИЯ О ЧАСОВОМ ПОЯСЕ МОЖЕТ МЕНЯТЬСЯ ДО ДВА РАЗА В ГОД
На самом деле больше. Сумасшествию политиков нет предела.
Вот более простой способ узнать местное время (tpl
):
auto tpl = tz->to_local(tp);
Я не рекомендую использовать sys_info
, если только вы не выполняете тысячи таких преобразований и вам не нужна максимальная производительность. Конечно, если вы только начинаете, просто позвольте time_zone
выполнить преобразование за вас.
нет, просто избегайте этого и используйте современное
std::chrono