Есть ли где-нибудь определение в стандартном пространстве имен, которое устанавливает вперед:
структура тм Имеет переменные-члены, которые должны быть в этих диапазонах, но я не могу найти определенные пределы в любом месте.
Я даже не уверен, есть ли локали, определенные там, где они не будут соответствовать обычному набору (12/7/24/60/60).
Даже если нет потенциальных пользователей с другими пределами диапазона, я бы определенно хотел использовать определение из стандартного пространства имен, а не произвольно определять свое собственное.
РЕДАКТИРОВАТЬ:
Похоже, я не первый, кто просит об этом: http://david.tribble.com/text/c0xcalendar.html
Я заметил, что в этом предложении есть упоминание о struct calendarinfo
который делает именно то, что я ищу.
Похоже, что последнее изменение было в 2009 году. Думаю, с тех пор ничего не произошло? Я думаю, это также означает, что этот материал не доступен для меня?
Больше информации, повышение :: локали :: календарь :: максимум кажется, выполняет именно то, что я ищу. Я не могу использовать Boost, но я уверен, что код в Boost является стандарт defacto о том, как придумать эти ограничения. К сожалению, я не могу добиться реализации maximum
, Может, кто-то еще здесь знает, как?
Стандарты C и C ++ абсолютно ничего не говорят ни о каком календаре, кроме григорианского, и не очень много о нем.
1.
Месяцы в году
Единственное, что вы найдете, это комментарий в стандарте C рядом с tm_mon
член tm
:
int tm_mon; // months since January -- [0, 11]
Ну, почти только. Вы также найдете %b
а также %B
спецификаторы в strftime
которые соответствуют сокращенным и полным названиям текущего языка, соответствующим tm_mon
,
2.
Дни в неделе
У тебя есть:
int tm_wday; // days since Sunday -- [0, 6]
а также %a
, %A
за strftime
,
3.
Часы в день
У тебя есть:
int tm_hour; // hours since midnight -- [0, 23]
Есть также strftime
спецификаторы, некоторые из которых чувствительны к текущей локали.
4.
Минут в час
int tm_min; // minutes after the hour -- [0, 59]
Также в этом случае вы получили некоторую помощь от нового C ++ 11 <chrono>
библиотека:
std::cout << std::chrono::hours{1}/std::chrono::minutes{1} << '\n';
Это будет переносимо (и последовательно) выводить 60
, Если ваш компилятор поддерживает constexpr
и вы беспокоитесь об эффективности, эта величина может быть интегральной константой времени компиляции:
constexpr auto minutes_per_hour = std::chrono::hours{1}/std::chrono::minutes{1};
Тип minutes_per_hour
гарантированно имеет целое число со знаком и не менее 29 бит.
5.
Секунд в минуту
Спецификация C немного интересна на этом:
int tm_sec; // seconds after the minutes -- [0, 60]
Диапазон не задокументирован как [0, 59]
так, чтобы учесть добавление положительной високосной секунды. При этом ни одна ОС, о которой я знаю, на самом деле не обеспечивает точного учета високосных секунд. Все, кажется, следуют Unix Time который отслеживает UTC кроме игнорирования високосных секунд. Когда происходит дополнительная секунда, все ОС, о которых я знаю, просто воспринимают это как обычную коррекцию часов. Google классно воспринимает это как мазок исправлений за некоторое время.
Дополнительно вы можете последовательно и переносимо написать:
std::cout << std::chrono::minutes{1}/std::chrono::seconds{1} << '\n';
и получить 60
,
Хотя это не определено стандартами C или C ++, каждая ОС, похоже, измеряет время с Новых 1970-х годов (пренебрегая високосными секундами). В C ++ 11 это количество доступно через:
auto tp = std::chrono::system_clock::now();
где tp
будет иметь тип std::chrono::system_clock::time_point
, это time_point
имеет неопределенную точность (две недели, секунды, фемтосекунды и т. д.). Точность обнаруживается программно во время компиляции.
В случае, если это полезно, эта ссылка содержит код, который можно перевести tp
в год / месяц / день час: минута: секунда и даже доли секунды (и наоборот). Ох, день недели, если вы тоже этого хотите (и несколько других календарных трюков). Этот код общественного достояния зависит от нестандартный но де-факто переносная эпоха Нового Года 1970 года. Она может быть легко перенесена в другие эпохи, если возникнет такая необходимость.
Я считаю, что я могу окончательно сказать, что есть не определение для любого из этих чисел в namespace std
,
Я основываю это утверждение на том факте, что Boost’s gregorian.cpp жесткие коды все эти значения в get_value
Если у вас есть Boost, вы можете использовать get_value
найти «Месяцы в году», «Дни в неделе» и «Часы в дне», выполнив:
locale::global(boost::locale::generator()(""));
cout.imbue(locale());
boost::locale::date_time now;
cout << "Months in a year: " << now.maximum(boost::locale::period::period_type(boost::locale::period::marks::month)) << endl;
cout << "Days in a week: " << now.maximum(boost::locale::period::period_type(boost::locale::period::marks::day_of_week)) << endl;
cout << "Hours in a day: " << now.maximum(boost::locale::period::period_type(boost::locale::period::marks::hour)) << endl;
Какие выводы:
Месяцев в году: 11
Дней в неделе: 7
Часов в день: 23
Обратите внимание на 0-месячные месяцы и часы и 1-дневные дни. Это согласуется с put_time«s %u
флаг.
Если у вас нет Boost, вам нужно определить их самостоятельно.
Говард Хиннантрешение для поиска «минут в час» и «секунд в минуту» является на самом деле основан в определяет из namespace std
:
cout << "Minutes in an hour: " << chrono::hours{1} / chrono::minutes{1} << endl;
cout << "Seconds in a minute: " << chrono::minutes{1} / chrono::seconds{1} << endl;
Какие выводы:
Минут через час: 60
Секунд в минуту: 60