elv*_*kaj 15 c++ crt msvcrt visual-c++
我正在使用Visual Studio c ++ Compiler(2010),但该库具有不同的ANSI C和POSIX库函数的实现.
ANSI C函数和Windows CRT实现有什么区别?例如tzset()和/ _tzset()或setenv()ans有_setenv()什么区别?似乎以同样的方式做同样的事情......
我正在使用msvc(2010),我是否更喜欢Windows CRT实现?
编辑1
好吧,我希望以可移植的方式转换一个以UTC表示的结构tm time_t,但是没有可移植的方法来做到这一点.我要为不同的平台(Android,Linux,Windows,Windows CE)编写功能.
我已经看过这个使用的stackoverflow帖子setenv,getenv和tzset
EDIT2
不幸的是,经过一些测试,我发现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;
}
Run Code Online (Sandbox Code Playgroud)
Nas*_*zta 20
我在Windows上使用以下宏:
#define timegm _mkgmtime
Run Code Online (Sandbox Code Playgroud)
因为_mkgmtime也是如此.
Ser*_*y D 11
// Algorithm: http://howardhinnant.github.io/date_algorithms.html
int days_from_epoch(int y, int m, int d)
{
y -= m <= 2;
int era = y / 400;
int yoe = y - era * 400; // [0, 399]
int doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1; // [0, 365]
int doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096]
return era * 146097 + doe - 719468;
}
// It does not modify broken-down time
time_t timegm(struct tm const* t)
{
int year = t->tm_year + 1900;
int month = t->tm_mon; // 0-11
if (month > 11)
{
year += month / 12;
month %= 12;
}
else if (month < 0)
{
int years_diff = (11 - month) / 12;
year -= years_diff;
month += 12 * years_diff;
}
int days_since_epoch = days_from_epoch(year, month + 1, t->tm_mday);
return 60 * (60 * (24L * days_since_epoch + t->tm_hour) + t->tm_min) + t->tm_sec;
}
Run Code Online (Sandbox Code Playgroud)
这是一种将 UTC 格式的 tm 转换为 time_t 的可移植方法。
请注意,它不会修改/标准化 tm 结构,也不会更改任何 tz 设置。
当David Cutler的团队在1989年开始使用Windows NT设计时,他们还不知道哪个api会占据主导地位.所以他们创造了三个.Win32是对16位版本的Windows API的改编.支持OS/2,该操作系统应该取代DOS但不支持.Posix是第三个,因为美国政府当时指出他们只会考虑使用遵循新兴Posix标准的操作系统.
你提到的tzset()函数是Posix api的遗留物.你可能拼错了putenv(),同样的故事.子系统运行得不好,Win32在很大程度上赢得了api之战,并且在2001年从Windows中删除了Posix支持.微软保留了对Posix功能的支持,但是由于它们不是标准的一部分,所以用一个领先的下划线重命名它们C库.当您使用函数的非前缀版本时,您应该获得弃用警告.听起来像#defined _CRT_NONSTDC_NO_DEPRECATE来压制它们.最好不要那样做.支持标准C库函数.
| 归档时间: |
|
| 查看次数: |
13809 次 |
| 最近记录: |