如何在Visual Studio C++ 2008中使用gettimeofday()或等效函数?

11

请问有人可以帮我在Windows XP上使用Visual Studio C++ 2008的gettimeofday()函数吗?这里有一段我从网上找到的代码:

#include < time.h >
#include <windows.h> 

#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
#else
  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
#endif

struct timezone 
{
  int  tz_minuteswest; /* minutes W of Greenwich */
  int  tz_dsttime;     /* type of dst correction */
};

int gettimeofday(struct timeval *tv, struct timezone *tz)
{
  FILETIME ft;
  unsigned __int64 tmpres = 0;
  static int tzflag;

  if (NULL != tv)
  {
    GetSystemTimeAsFileTime(&ft);

    tmpres |= ft.dwHighDateTime;
    tmpres <<= 32;
    tmpres |= ft.dwLowDateTime;

    /*converting file time to unix epoch*/
    tmpres -= DELTA_EPOCH_IN_MICROSECS; 
    tmpres /= 10;  /*convert into microseconds*/
    tv->tv_sec = (long)(tmpres / 1000000UL);
    tv->tv_usec = (long)(tmpres % 1000000UL);
  }

  if (NULL != tz)
  {
    if (!tzflag)
    {
      _tzset();
      tzflag++;
    }
    tz->tz_minuteswest = _timezone / 60;
    tz->tz_dsttime = _daylight;
  }

  return 0;
}

...
// call gettimeofday()
 gettimeofday(&tv, &tz); 
 tm = localtime(&tv.tv_sec); 

去年我使用VC++6测试这段代码时,它运行良好。但现在我使用VC++ 2008时,出现了异常处理错误。请问是否有任何想法可以使用gettimeofday或类似的东西?

感谢您的回复,非常感谢任何帮助:


你能贴出你遇到的异常吗? - Jason
请解释您实际遇到的错误--“异常处理错误”并不是很具体。 - JSBձոգչ
感谢您的回复!我已经在http://stackoverflow.com/questions/2490449/how-to-solve-unhandled-exception-error-when-using-visual-c-2008上发布了一个关于这个错误的问题。再次感谢您的回复。 - make
请不要多次发布相同的问题。重复的链接为http://stackoverflow.com/questions/2490449/how-to-solve-unhandled-exception-error-when-using-visual-c-2008/2494647#2494647。 - interjay
1
抱歉发了多篇帖子。由于我需要帮助解决这个问题,在尝试解决它的过程中发布了不同的问题...再次感谢! - make
注意:此代码缺少对 'tv' 和 'tz' 参数的空值检查,如果用户在这些参数中发送了空值,则很可能会导致程序崩溃。请参见以下摘自 'gettimeofday' 的说明:“如果 tv 或 tz 任一为 NULL,则相应的结构体不会被设置或返回。时区结构的使用已过时;tz 参数通常应指定为 NULL。” - avner
4个回答

20
在UNIX中,timezone结构的使用已经过时。我不知道为什么你要使用它。请参考http://linux.about.com/od/commands/l/blcmdl2_gettime.htm。但是,如果您想使用此结构来了解本地时间与GMT(UTC)的差异,可以按照以下方式操作:tz_minuteswest是实际与GMT(UTC)的分钟差异,而tz_dsttime是指示当前是否使用夏令时的标志。
在Visual C++ 2008 Express中,您的示例稍作更改即可正常工作。
#include "stdafx.h"
#include <time.h>
#include <windows.h> 

const __int64 DELTA_EPOCH_IN_MICROSECS= 11644473600000000;

/* IN UNIX the use of the timezone struct is obsolete;
 I don't know why you use it. See http://linux.about.com/od/commands/l/blcmdl2_gettime.htm
 But if you want to use this structure to know about GMT(UTC) diffrence from your local time
 it will be next: tz_minuteswest is the real diffrence in minutes from GMT(UTC) and a tz_dsttime is a flag
 indicates whether daylight is now in use
*/
struct timezone2 
{
  __int32  tz_minuteswest; /* minutes W of Greenwich */
  bool  tz_dsttime;     /* type of dst correction */
};

struct timeval2 {
__int32    tv_sec;         /* seconds */
__int32    tv_usec;        /* microseconds */
};

int gettimeofday(struct timeval2 *tv/*in*/, struct timezone2 *tz/*in*/)
{
  FILETIME ft;
  __int64 tmpres = 0;
  TIME_ZONE_INFORMATION tz_winapi;
  int rez=0;

   ZeroMemory(&ft,sizeof(ft));
   ZeroMemory(&tz_winapi,sizeof(tz_winapi));

    GetSystemTimeAsFileTime(&ft);

    tmpres = ft.dwHighDateTime;
    tmpres <<= 32;
    tmpres |= ft.dwLowDateTime;

    /*converting file time to unix epoch*/
    tmpres /= 10;  /*convert into microseconds*/
    tmpres -= DELTA_EPOCH_IN_MICROSECS; 
    tv->tv_sec = (__int32)(tmpres*0.000001);
    tv->tv_usec =(tmpres%1000000);


    //_tzset(),don't work properly, so we use GetTimeZoneInformation
    rez=GetTimeZoneInformation(&tz_winapi);
    tz->tz_dsttime=(rez==2)?true:false;
    tz->tz_minuteswest = tz_winapi.Bias + ((rez==2)?tz_winapi.DaylightBias:0);

  return 0;
}


int _tmain(int argc, _TCHAR* argv[])
{
struct timeval2 tv;
struct timezone2 tz;
struct tm *tm1; 
time_t time1;

ZeroMemory(&tv,sizeof(tv));
ZeroMemory(&tz,sizeof(tz));

gettimeofday(&tv, &tz); // call gettimeofday()
time1=tv.tv_sec;
tm1 = localtime(&time1); 



 FILE *f;
 f=fopen("rez.txt","w");

 fprintf(f,"%04d.%02d.%02d %02d:%02d:%02d\n",1900+tm1->tm_year,1+tm1->tm_mon,tm1->tm_mday,tm1->tm_hour,tm1->tm_min,tm1->tm_sec);
 fprintf(f,"Diffrence between GMT(UTC) and local time=%d %s\n",tz.tz_minuteswest,"minutes");
 fprintf(f,"Is Daylight now=%s\n",tz.tz_dsttime?"Yes":"No");

 fclose(f);
 return 0;
}

这对我很有帮助,但我需要更精确的时间。我使用了GetSystemTimePreciseAsFileTime代替GetSystemTimeAsFileTime,它完美地工作了。干杯。 - Shawn Blakesley

4

简单秒表

顺带一提:这是一个类似于Kate的简单秒表,但我只是想提一下,如果有人正在寻找最简单的C++秒表(计算秒数)。并不是很重要,它只有1秒的分辨率,所以如果您想计算微秒,请使用其他示例。

double seconds=0;
time_t timer1, timer2;
time(&timer1);  /* get current time  */
...
time(&timer2);  /* get current time  later */
seconds = difftime(timer2,timer1);

3

有几种不同的方式可以表示时间。这是我最近使用的一些代码:

time_t now;
time(&now); 
tm* local = localtime(&now);

然后,我开始从local的各个部分构建字符串,但在这一点上,您可以按照自己的意愿进行操作。


非常感谢您的回复。是的!我可以使用time()函数,但它不像gettimeofday()函数那样精确,这给我带来了问题,因为我正在尝试将我在Unix上获得的结果与我将在Windows上获得的结果进行比较。再次感谢! - make

1
在我的情况下,它的工作方式如下: 由于我想找到平均运行时间,所以使用了以下步骤: 首先在程序开头包含<chrono>, 然后初始化样本为100(例如);
time_t t_start,t_end;
time(&t_start); //get the current time

//program that needs to be timed

time(&t_end); //get the time at the end of execution of the program
seconds = (difftime(t_start,t_end))/samples;//calculate the difference

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接