2

Is there a definition somewhere in the standard namespace that sets forward:

  1. Months in a year
  2. Days in a week
  3. Hours in a day
  4. Minutes in an hour
  5. Seconds in a minute

The struct tm has contains member variables that must be in these ranges, but I can't find the defined limits anywhere.

I'm not even sure if there are locales defined where these wouldn't match the conventional set (12/7/24/60/60).

Even if there aren't potential users with other range limits, I'd sure like to use a define from the standard namespace rather than arbitrarily defining my own.

EDIT:

It looks like I'm not the first to ask for such a thing: http://david.tribble.com/text/c0xcalendar.html I notice in this proposal there is mention of the struct calendarinfo which does exactly what I'm looking for.

It looks like the last change on this was 2009. I guess nothing's happened since then? I guess that also means this stuff is not readily available to me?

More info, boost::locale::calendar::maximum seems to accomplish exactly what I'm looking for. I can't use Boost, but I'm certain that the code in Boost is the defacto standard on how to come up with these limits. Unfortuantely I can't seem to get at the implementation of maximum. Maybe someone else here knows how?

4

2 回答 2

1

除了公历之外,C 和 C++ 标准对任何日历都没有任何规定,关于那个日历也没有太多说明。

1.一年中的几个月

您会发现的唯一内容是 C 标准中的tm_mon成员旁边的注释tm

int tm_mon;  // months since January -- [0, 11]

好吧,几乎只有。您还将在其中找到对应于当前语言环境的缩写和完整月份名称的说明符,%b其中对应于.%Bstrftimetm_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]以便允许添加正闰秒。话虽如此,我所知道的操作系统实际上没有实现对闰秒的准确计算。除了忽略闰秒之外,每个人似乎都遵循跟踪 UTC 的Unix 时间。当闰秒发生时,我所知道的所有操作系统都只是将其视为普通的时钟校正。众所周知,谷歌将其视为一段时间内的修正涂片

此外,您可以一致且可移植地编写:

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 年新年时代。如果需要,它可以很容易地被其他时代采用。

于 2015-02-17T02:32:02.793 回答
0

我相信我可以肯定地说namespace std.

我基于 Boost 的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%u标志一致。

如果您没有 Boost,则需要自己定义这些。

Howard Hinnant用于查找“一小时内的分钟数”和“一分钟内的秒数”的解决方案实际上基于以下定义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

于 2015-02-17T15:44:47.550 回答