关于time_t要注意的一个问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jewelsu/article/details/78806318

最近需要做一个这样的需求,计算当前时间和某个特定时间之间的天数。貌似是一个很简单的任务。于是写了一段代码:


....... 

int year=2019;

int month=2;

int day=1;

struct tm schedule_start_time ;
   schedule_start_time.tm_year=year-1900;
   schedule_start_time.tm_mon=month-1;
   schedule_start_time.tm_mday=day;
   schedule_start_time.tm_hour=0;
   schedule_start_time.tm_min=0;
   schedule_start_time.tm_sec=0;
   schedule_start_time.tm_isdst = 0;


   time_t schedule_start,now_time;
   double diff_secs;
   int diff_days;

   schedule_start=mktime(&schedule_start_time);
   now_time=time(NULL);

   diff_secs=difftime(now_time,schedule_start);
   diff_days=(int)diff_secs/(3600*24);

   char timE[80];
   strftime(timE,80,"From Date: %Y-%m-%d Time: %I:%M:%S\n",&schedule_start_time);
  printf("%s passed  about %ddays",timE,diff_days);

添加到系统里,简单测试一下,没有问题,在vs2010上编译,在linux下编译,交给测试。

结果测试反馈,说结果不对。当输入的时间是2039年的时候就不对了。

在自己的环境下跑了一遍,果然不对,mktime返回的值时-1.又把这一段单独写了一个demo程序,运行居然没错。

于是一阵查找,终于找到了原因。

time_t类型实际上是long类型,表示从1970年1月1日0时0分0秒到此时的秒数,long类型在32位的机器上是4个字节的,自然也就有长度,很悲催的是,这个长度换算过来是

2038年1月18日19时14分07秒,也就是说,time_t表示的时间不能超过这个时间。针对这个问题,微软从vs2008之后默认改成了64位的time_t,如果想继续使用32位的,需要定义_USE_32BIT_TIME_T,这也就是为什么我的demo程序对的原因了,而在系统环境下,增加了这个预处理器定义,所以是错的。linux系统下也没有这个扩展,所以也是错的。

linux下的问题怎么处理呢?想到了几个思路

第一个自然像windows一样扩展为64位,可是没有发现通过增加编译选项或者修改定义的方法。

第二个是不使用time_t,自己写这个mktime,这样就可以只计算分钟数,可是却发现没有办法获取当期时间,找到的函数在获取当前时间的时候都使用了time_t,仍然无法避免这个问题。

第三个,换64位系统,这个近期内不太可能实现。


最后的解决方案是,不去解决,直接限制输入,填写不能超过这个时间。等快到了2038年,硬件系统肯定能升级到64位,自然也就不用解决了。



猜你喜欢

转载自blog.csdn.net/jewelsu/article/details/78806318
今日推荐