我使用std::mktime在我的程序中设置/获取时间。手册页告诉:
允许时间值超出正常范围。
并且如果它不能将结果表示为std :: time_t
,则返回-1我在单元测试中尝试了所有内容以使此功能失败,但没有成功。 These只是一些尝试:
#include <iostream>
#include <iomanip>
#include <ctime>
#include <stdlib.h>
int main()
{
setenv("TZ", "/usr/share/zoneinfo/America/New_York", 1); // POSIX-specific
std::time_t t = std::time(nullptr);
std::tm tm = *std::localtime(&t);
std::cout << "Today is " << std::put_time(&tm, "%c %Z")
<< " and DST is " << (tm.tm_isdst ? "in effect" : "not in effect") << '\n';
tm.tm_year = 550;
tm.tm_year = 123456789;
tm.tm_mon = 88;
tm.tm_mday = 200;
//tm.tm_mon -= 100; // tm_mon is now outside its normal range
std::mktime(&tm); // tm_dst is not set to -1; today's DST status is used
std::cout << "100 months ago was " << std::put_time(&tm, "%c %Z")
<< " and DST was " << (tm.tm_isdst ? "in effect" : "not in effect") << '\n';
}
那么,如何设置参数以使此功能失效?
正如评论中所建议的,I tried INT_MAX并且它仍然没有失败。所以,这个:
tm.tm_year = std::numeric_limits< decltype( tm.tm_year ) >::max();
if ( -1 == std::mktime(&tm) )
std::cout << "std::mktime() failed)" << '\n';
仍然不会让它失败。
$CXX --version
aarch64-pdm3-linux-g++ (GCC) 6.4.0
答案 0 :(得分:2)
您的示例确实因建议的输入std::numeric_limits< decltype( tm.tm_year ) >::max()
而失败。您的示例不检查-1返回值。如果你添加
auto err = std::mktime(&tm); // tm_dst is not set to -1, err is.
此输入的 err
设置为-1。
您还可以在http://coliru.stacked-crooked.com/a/8288579ec8924d7e
看到失败两项服务的输出相同:
Today is Thu Apr 19 09:07:40 2018 EDT and DST is in effect
100 months ago was Thu ? 200 09:07:40 -2147481749 EDT and DST was in effect
-1
答案 1 :(得分:1)
mktime
将无法更新tm
结构,例如当年份设置为INT_MAX
并且添加超过12个月(超过一年)。像这样:
std::tm tm;
tm.tm_year = INT_MAX;
tm.tm_mon = 13;
std::time_t rc = std::mktime(&tm);
如果您将年份设置为tm
,将月份设置为零并减去一天(将INT_MIN
设置为0并tm_mon
,则也无法更新tm_mday
结构到-1):
std::tm tm;
tm.tm_year = INT_MIN;
tm.tm_mon = 0;
tm.tm_mday = -1;
std::time_t rc = std::mktime(&tm);
如果月份和tm_mday的组合仍然少于一年,那么当年份设置为INT_MAX
时不会失败,因为这仍然是可表示的!
然而,正如MSalters所提到的,这并不总是导致-1作为返回值。有时mktime
将无法将时间戳标准化为有效的tm
结构时返回-1。但是,根据实现mktime
,只有在time_t
中无法表达时间时才返回-1(自从time_t未指定时可能永远不会)。在后一种情况下,假设将tm结构规范化为有效值实际上是危险的。