C++ localtime返回在cygwin Shell上运行的windows程序的GMT
考虑以下代码:C++ localtime返回在cygwin Shell上运行的windows程序的GMT,c++,c,time,cygwin,C++,C,Time,Cygwin,考虑以下代码: time_t t; t = time( NULL ); elog << "timezone: " << getenv( "TZ" ) << ", current local time: " << asctime( localtime( &t )); 但是,如果我在cygwin shell(如bash)下运行相同的程序,那么这段代码将返回GMT timezone: America/New_York, curren
time_t t;
t = time( NULL );
elog << "timezone: " << getenv( "TZ" )
<< ", current local time: " << asctime( localtime( &t ));
但是,如果我在cygwin shell(如bash)下运行相同的程序,那么这段代码将返回GMT
timezone: America/New_York, current local time: Wed Jul 25 18:05:08 2012
如果我在Linux或OsX中运行这个程序,它也会返回正确的本地时间
为什么?
@更新:现在是一年后,我发现我下面给出的答案并不总是有效的
似乎对于某些程序,TZ并不总是起作用。我不知道为什么。但有一个麻烦的解决办法。基本上,在取消设置TZ之后,您必须检查本地时间是否确实不再返回GMT,但前提是您实际上不在GMT时区,并在调用localtime()或maketime()时计算对时间的手动调整
致电当地时间:
time_t t = getAtTimeFromSomewhere();
t -= localTimeOffset;
timeInfo = localtime( &t );
对maketime的调用:
struct tm timestr;
makeATMFromAStringForExample( time, timestr );
time_t timet = mktime( ×tr );
timet += localTimeOffset;
好时光。我花了一些时间才弄明白,我希望它对其他人有用 POSIX函数如
localtime
将使用环境变量TZ
来确定要使用的时区。如果未设置TZ
,则将使用系统的默认时区
如果我在Linux或OS X下运行,TZ
设置正确,一切正常。如果我在Windows上的shell中运行此程序,TZ
未设置,因此该函数返回操作系统的默认时区,从而再次生成正确的结果
如果我在Cygwin shell中运行,TZ
已设置-但由于我使用MSVC构建程序,使用MSVC自己的stdc库-它无法解释Cygwin的TZ
变量。所以它默认为GMT
如果该程序是在Cygwin下用GCC构建的,我打赌它在Cygwin shell中会正常工作
因此,答案是确保在调用POSIX时间函数(如localtime()
)的程序中,如果希望时间函数在Cygwin shell下正常工作,则必须取消设置TZ
我是这样做的:
void getLocalTime()
{
#ifdef WIN32
static bool unsetTZ = false;
if ( !unsetTZ )
{
putenv( "TZ=" );
unsetTZ = true;
}
#endif // !WIN32
time_t t;
t = time( NULL );
elog << "timezone: " << getenv( "TZ" )
<< ", current local time: " << asctime( localtime( &t ));
}
void getLocalTime()
{
#ifdef WIN32
静态bool unsetz=false;
如果(!unsetz)
{
putenv(“TZ=”);
unsetz=真;
}
#endif//!WIN32
时间;
t=时间(空);
elog尝试在struct tm中设置tm_isdst标志
如果夏令时生效,则夏令时标志(tm_isdst)大于零;如果夏令时未生效,则为零;如果信息不可用,则小于零
如果我记得清楚的话,在Windows中它必须是-1才能正常工作。在Cygwin shell中使用export TZ=“”
可能是最好的方法
@更新
嗨,Tunaki。谢谢你的编辑!DST不能解释5小时的差异。哎哟..对不起,你完全正确。我没有看到5小时的差异。问题是我在linux/windows上遇到了类似的问题,我正确地设置了DST解决了它。putenv(“TZ=”)
实际上并没有取消设置TZ;它将其设置为空字符串。我不知道这是否重要,但您可以尝试使用unsetenv(“TZ”)
来代替。谢谢您的帮助。我查看了它。Windows没有unsetenv。要取消设置变量,请使用putenv将其设置为空字符串。在cygwin下,运行“unsetTz”就足够了
struct tm timestr;
makeATMFromAStringForExample( time, timestr );
time_t timet = mktime( ×tr );
timet += localTimeOffset;
void getLocalTime()
{
#ifdef WIN32
static bool unsetTZ = false;
if ( !unsetTZ )
{
putenv( "TZ=" );
unsetTZ = true;
}
#endif // !WIN32
time_t t;
t = time( NULL );
elog << "timezone: " << getenv( "TZ" )
<< ", current local time: " << asctime( localtime( &t ));
}