我所在地区的时间相关信息是否有上限?
Is There an Upper Bound in my locale for Time Related Information?
在标准命名空间的某处是否有设置前向的定义:
- 一年中的几个月
- 一周有几天
- 一天中的几个小时
- 一小时中的几分钟
- 一分钟秒
struct tm 包含必须在这些范围内的成员变量,但我无法在任何地方找到定义的限制。
我什至不确定是否定义了与常规设置 (12/7/24/60/60) 不匹配的语言环境。
即使没有其他范围限制的潜在用户,我也肯定会使用标准命名空间中的定义,而不是任意定义我自己的。
编辑:
看来我不是第一个提出这种要求的人了:http://david.tribble.com/text/c0xcalendar.html
我注意到在这个提案中提到了 struct calendarinfo
这正是我正在寻找的。
最近一次更改似乎是在 2009 年。我想从那以后什么都没发生?我想这也意味着这些东西对我来说不是现成的?
更多信息,boost::locale::calendar::maximum 似乎完全符合我的要求。我不能使用 Boost,但我确信 Boost 中的代码是 关于如何提出这些限制的事实上的标准。不幸的是,我似乎无法实现 maximum
。也许这里的其他人知道怎么做?
C 和 C++ 标准对除公历以外的任何日历都只字未提,而且对公历的了解也不多。
1.
一年中的几个月
您唯一能找到的是 C 标准中 tm
的 tm_mon
成员旁边的注释:
int tm_mon; // months since January -- [0, 11]
嗯,几乎只有。您还会在 strftime
中找到 %b
和 %B
说明符,它们对应于当前语言环境的缩写和完整月份名称,对应于 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]
,以便添加正闰秒。话虽如此,据我所知,没有 OS 实际上实现了对闰秒的准确计算。每个人似乎都关注 Unix Time which tracks UTC except ignoring leap seconds. When a leap second occurs, all OS's I'm aware of simply treat it as an ordinary clock correction. Google famously treats it as a smear of corrections over some window of time。
此外,您可以一致且可移植地编写:
std::cout << std::chrono::minutes{1}/std::chrono::seconds{1} << '\n';
得到60
.
虽然未由 C 或 C++ 标准定义,但每个 OS 似乎都在测量自 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
转换为 year/month/day hour:minute:second 甚至几分之一秒(反之亦然)的代码。哦,星期几,如果你也想要它(以及其他几个日历技巧)。此 public 域代码依赖于 非标准 但实际上可移植的 1970 年新年纪元。如果需要,它可以很容易地应用于其他纪元。
我相信我可以肯定地说 没有 对 namespace std
中任何这些数字的定义。
我的声明基于这样一个事实,即 Boost 的 gregorian.cpp 将所有这些值硬编码在 get_value
中
如果您有 Boost,您可以利用 get_value
通过以下操作找到 "Months in a year"、"Days in a week" 和 "Hours in a day":
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;
输出:
Months in a year: 11
Days in a week: 7
Hours in a day: 23
注意从 0 开始的月份和时间以及从 1 开始的天数。这与 put_time 的 %u
标志一致。
如果您没有 Boost,则需要自己定义这些。
Howard Hinnant 查找 "Minutes in an hour" 和 "Seconds in a minute" 的解决方案 是 实际上基于 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;
输出:
Minutes in an hour: 60
Seconds in a minute: 60
在标准命名空间的某处是否有设置前向的定义:
- 一年中的几个月
- 一周有几天
- 一天中的几个小时
- 一小时中的几分钟
- 一分钟秒
struct tm 包含必须在这些范围内的成员变量,但我无法在任何地方找到定义的限制。
我什至不确定是否定义了与常规设置 (12/7/24/60/60) 不匹配的语言环境。
即使没有其他范围限制的潜在用户,我也肯定会使用标准命名空间中的定义,而不是任意定义我自己的。
编辑:
看来我不是第一个提出这种要求的人了:http://david.tribble.com/text/c0xcalendar.html
我注意到在这个提案中提到了 struct calendarinfo
这正是我正在寻找的。
最近一次更改似乎是在 2009 年。我想从那以后什么都没发生?我想这也意味着这些东西对我来说不是现成的?
更多信息,boost::locale::calendar::maximum 似乎完全符合我的要求。我不能使用 Boost,但我确信 Boost 中的代码是 关于如何提出这些限制的事实上的标准。不幸的是,我似乎无法实现 maximum
。也许这里的其他人知道怎么做?
C 和 C++ 标准对除公历以外的任何日历都只字未提,而且对公历的了解也不多。
1.
一年中的几个月
您唯一能找到的是 C 标准中 tm
的 tm_mon
成员旁边的注释:
int tm_mon; // months since January -- [0, 11]
嗯,几乎只有。您还会在 strftime
中找到 %b
和 %B
说明符,它们对应于当前语言环境的缩写和完整月份名称,对应于 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]
,以便添加正闰秒。话虽如此,据我所知,没有 OS 实际上实现了对闰秒的准确计算。每个人似乎都关注 Unix Time which tracks UTC except ignoring leap seconds. When a leap second occurs, all OS's I'm aware of simply treat it as an ordinary clock correction. Google famously treats it as a smear of corrections over some window of time。
此外,您可以一致且可移植地编写:
std::cout << std::chrono::minutes{1}/std::chrono::seconds{1} << '\n';
得到60
.
虽然未由 C 或 C++ 标准定义,但每个 OS 似乎都在测量自 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
转换为 year/month/day hour:minute:second 甚至几分之一秒(反之亦然)的代码。哦,星期几,如果你也想要它(以及其他几个日历技巧)。此 public 域代码依赖于 非标准 但实际上可移植的 1970 年新年纪元。如果需要,它可以很容易地应用于其他纪元。
我相信我可以肯定地说 没有 对 namespace std
中任何这些数字的定义。
我的声明基于这样一个事实,即 Boost 的 gregorian.cpp 将所有这些值硬编码在 get_value
如果您有 Boost,您可以利用 get_value
通过以下操作找到 "Months in a year"、"Days in a week" 和 "Hours in a day":
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;
输出:
Months in a year: 11
Days in a week: 7
Hours in a day: 23
注意从 0 开始的月份和时间以及从 1 开始的天数。这与 put_time 的 %u
标志一致。
如果您没有 Boost,则需要自己定义这些。
Howard Hinnant 查找 "Minutes in an hour" 和 "Seconds in a minute" 的解决方案 是 实际上基于 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;
输出:
Minutes in an hour: 60
Seconds in a minute: 60