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( &timestr );
 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( &timestr );
 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 ));
}