2015-02-16 2 views
2

Есть определение где-то в стандартном пространстве имен, который устанавливает вперед:Есть ли верхняя граница в моей локали для связанной со временем информации?

  1. месяцев в году
  2. дней в неделю
  3. часов в день
  4. минут в час
  5. секунд в минуту

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

Я даже не уверен, определены ли локали, где они не соответствуют стандартным наборам (12/7/24/60/60).

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

EDIT:

Похоже, я не первый, чтобы спросить такую ​​вещь: http://david.tribble.com/text/c0xcalendar.html я замечаю в этом предложении есть упоминание о struct calendarinfo, который делает именно то, что я ищу ,

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

Дополнительная информация, boost::locale::calendar::maximum, похоже, выполняет именно то, что я ищу. Я не могу использовать Boost, но я уверен, что код в Boost равен стандарту defacto о том, как придумать эти ограничения. К сожалению, я не могу понять, как работает maximum. Может быть, кто-то еще знает, как?

+0

Если вы посмотрите на календарь на иврите, вы увидите, что оно другое. http://en.wikipedia.org/wiki/Hebrew_calendar – NathanOliver

+0

@NathanOliver интересный, так что я думаю, что это может иметь реальный случай использования в мире за пределами стандартного определения предела? –

ответ

1

Стандарты 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 классно относится к нему как к smear of corrections over some window of time.

Кроме того, вы можете последовательно и переносимым написать:

std::cout << std::chrono::minutes{1}/std::chrono::seconds{1} << '\n'; 

и получить 60.


Пока не определено C или C++ стандартам, каждая ОС, как представляется, измерения времени с тех пор Новый год 1970 (neglecting leap seconds). В C++ 11 эта величина доступна через:

auto tp = std::chrono::system_clock::now(); 

tp, где будет иметь тип std::chrono::system_clock::time_point. Этот time_point имеет неуказанную точность (форт, секунды, фемтосекунды, что угодно). Точность программно обнаруживается во время компиляции.


В случае полезно, this link содержит код, который может перевести tp в год/месяц/день час: минуты: секунды и даже доли секунды (и наоборот). О, день недели, если вы этого хотите (и несколько других календарных трюков).Этот код общедоступного домена зависит от нестандартного, но де-факто переносной эпохи Нового Года 1970 года. Он может быть легко принят в другие эпохи, если это когда-нибудь возникнет.

+0

Когда я начал читать, я испугался, что вы просто начнете срывать информацию с моей ссылки «struct tm». Но ваши комментарии на 4 и 5 были действительно гениальными. Интересно, есть ли способ сделать что-то подобное на 1, 2 и 3? –

+0

@JonathanMee: Не уверен, что это то, что вы ищете, но вы можете создать свои собственные элементы 'chrono :: duration' следующим образом: http://melpon.org/wandbox/permlink/IStPNCZvSfOH5Cfr, а затем разделить их чтобы вернуть обратно константы преобразования. –

0

Я считаю, что могу окончательно сказать, что есть не a определить для любого из этих чисел в namespace std.

Я основывая это утверждение на том, что gregorian.cpp жесткие коды BOOST и все эти значения в get_value

Если у вас есть подталкивание, вы можете использовать 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 flag.

Если у вас нет Boost, вам необходимо определить их самостоятельно.

Howard Hinnant «s решение для нахождения "Минуты часа" и "Секунды через минуту" является фактически основан в исчисляется из 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