鄙人在SuSE linux 64位服务器编程,今天有一个功能跟客户端同事联调,其中一步骤是关于今天的凌晨时间的判断,两边一直差异较大。
与他沟通之后,才知道是凌晨时间计算方法的差异。
客户端(windows)的同事的计算方法如下:
time_t cur_time = time(NULL);
time_t morning = cur_time - cur_time % 86400; //86400 = 24 * 60 * 60
貌似很简单,但是不正确,先给出提醒,中国的时区是在东八区。
下面是我的一段代码:
#include <stdio.h>
#include <time.h>
#include <string.h>
#define u8 unsigned int
#define n8 long int
n8 get_sec_of_morning(n8 sec) {
struct tm sec_tm;
localtime_r((time_t*)&sec, &sec_tm);
struct tm morning_tm;
memset(&morning_tm, 0, sizeof(morning_tm));
morning_tm.tm_year = sec_tm.tm_year;
morning_tm.tm_mon = sec_tm.tm_mon;
morning_tm.tm_mday = sec_tm.tm_mday;
return mktime(&morning_tm);
}
n8 get_sec_of_day(n8 sec) {
return sec - get_sec_of_morning(sec);
}
int main(int argc, char** argv) {
time_t sec = time(NULL);
time_t morning = get_sec_of_morning(sec);
printf("%ld, cur sec %s\n", sec, ctime(&sec));
printf("%ld, morning hour of today: %s\n", morning, ctime(&morning));
printf("time difference from morning: %ld\n", get_sec_of_day(sec))
time_t morning2 = sec - sec % 86400;
printf("%ld, cur sec %s\n", sec, ctime(&sec));
printf("%ld, morning hour of today: %s\n", morning2, ctime(&morning2));
return 0;
}
上面的程序在SuSE linux 64bit server上运行之后,根据运行结果,可以看到上面那个貌似简单的方法是谬之千里的原因就是time(time_t*)函数返回的是从1970年1月1日至今的秒数,即UTC时间,而非当前时区的当前时间。
函数get_sec_of_morning(n8)借助了localtime_r(time_t*, struct tm*)计算出本time zone的当前时间,然后进行时间计算,这一步是关键。
另外,函数get_sec_of_day(n8 sec)函数返回自秒sec所在当天的凌晨时间到秒sec的秒数difference。