我使用的是Visual Studio c++ Compiler(2010),但该库具有ANSI C和POSIX库函数的不同实现。
ANSI C函数和Windows CRT实现之间有什么区别?例如,tzset()
和_tzset()
或setenv()
和_setenv()
之间有什么区别?似乎他们以同样的方式做着同样的事情…
我正在使用msvc(2010),我是否更喜欢Windows CRT实现?
编辑1
我想以一种可移植的方式转换一个在time_t
中用UTC表示的结构体,但是没有可移植的方法来做到这一点。我必须为不同的平台(Android,Linux,Windows,Windows CE)编写函数。
我见过使用setenv
、getenv
和tzset
的this stackoverflow post
编辑2
不幸的是,经过一些测试,我发现getenv("TZ")
在windows上返回空指针。但是为什么将UTC时间结构转换为time_t
如此困难呢?
编辑3
在Boost中,我在boost/chrono/io/time_point_io. hpp中发现了这段代码。希望这对我有帮助。
inline int32_t is_leap(int32_t year)
{
if(year % 400 == 0)
return 1;
if(year % 100 == 0)
return 0;
if(year % 4 == 0)
return 1;
return 0;
}
inline int32_t days_from_0(int32_t year)
{
year--;
return 365 * year + (year / 400) - (year/100) + (year / 4);
}
inline int32_t days_from_1970(int32_t year)
{
static const int days_from_0_to_1970 = days_from_0(1970);
return days_from_0(year) - days_from_0_to_1970;
}
inline int32_t days_from_1jan(int32_t year,int32_t month,int32_t day)
{
static const int32_t days[2][12] =
{
{ 0,31,59,90,120,151,181,212,243,273,304,334},
{ 0,31,60,91,121,152,182,213,244,274,305,335}
};
return days[is_leap(year)][month-1] + day - 1;
}
inline time_t internal_timegm(std::tm const *t)
{
int year = t->tm_year + 1900;
int month = t->tm_mon;
if(month > 11)
{
year += month/12;
month %= 12;
}
else if(month < 0)
{
int years_diff = (-month + 11)/12;
year -= years_diff;
month+=12 * years_diff;
}
month++;
int day = t->tm_mday;
int day_of_year = days_from_1jan(year,month,day);
int days_since_epoch = days_from_1970(year) + day_of_year;
time_t seconds_in_day = 3600 * 24;
time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec;
return result;
}
5条答案
按热度按时间8gsdolmq1#
我在Windows上使用以下宏:
正如_mkgmtime所做的一样。
xfb7svmp2#
当大卫Cutler的团队在1989年开始设计Windows NT时,他们还不知道哪种API将占主导地位。他们创造了三个人。Win32是Windows API的16位版本的改编。支持OS/2,该操作系统本应取代DOS,但没有。Posix是第三个,因为当时美国政府规定他们只会考虑使用遵循新兴Posix标准的操作系统。
你提到的tzset()函数是Posix API的遗留。你可能拼错了putenv(),同样的故事。这个子系统的表现并不好,Win32在API之战中大获全胜,Posix的支持在2001年从Windows中删除。微软保留了对Posix函数的支持,但使用前导下划线重命名了它们,因为它们不是标准C库的一部分。当你使用函数的无前缀版本时,你应该得到弃用警告。听起来像是#defined _CRT_NONSTDC_NO_DEPRECATE来抑制它们。最好不要这样做。支持标准C库函数。
qybjjes13#
这是一种将UTC中的tm转换为time_t的可移植方法。
请注意,它不会修改/标准化tm结构,也不会更改任何tz设置。
cgh8pdjw4#
对于我所知道的大多数功能来说,没有区别。
名称中的下划线是为了强调这些不是标准的C函数:另外,ANSI C中没有
tzset
和setenv
函数。它们主要是由MS CRT实现的POSIX函数,作为从其他操作系统移植的辅助工具。但他们不声称POSIX兼容性,这就是为什么下划线。这就是为什么你应该仔细阅读有关这些函数的MS文档。那里有恶魔!
guykilcj5#
我的
timegm
实现在windows上运行。应该没问题