【发布时间】:2009-07-23 18:19:51
【问题描述】:
我需要在 C 中的时区之间转换时间(在 linux 上,所以任何特定的东西也可以)。
我知道我的当前时间,本地时间和UTC,我有目标时间的偏移量。我正在尝试使用 mktime、gmtime、localtime 和类似的功能集,但仍然无法弄清楚。
提前致谢。
【问题讨论】:
我需要在 C 中的时区之间转换时间(在 linux 上,所以任何特定的东西也可以)。
我知道我的当前时间,本地时间和UTC,我有目标时间的偏移量。我正在尝试使用 mktime、gmtime、localtime 和类似的功能集,但仍然无法弄清楚。
提前致谢。
【问题讨论】:
由于 cmets 不允许发布代码,因此作为单独的答案发布。如果您知道“本地”时间和“UTC”时间,则可以计算“其他”时间与“本地”时间的偏移量。然后将 struct tm 转换为日历时间,添加所需的秒数(即目标时间的偏移量),并将其转换回 struct tm:
(编辑以考虑使用 mktime 标准化的另一种情况)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
int main(int argc, char *argv) {
struct timeval tv_utc;
struct tm *local_tm, *other_tm;
/* 'synthetic' time_t to convert to struct tm for the other time */
time_t other_t_synt;
/* Other time is 1 hour ahead of local time */
int other_local_delta = 1*3600;
/* the below two lines are just to set local_tm to something */
gettimeofday(&tv_utc, NULL);
local_tm = localtime(&tv_utc.tv_sec);
printf("Local time: %s", asctime(local_tm));
#ifdef DO_NOT_WRITE_TO_LOCAL_TM
other_t_synt = mktime(local_tm) + other_local_delta;
#else
local_tm->tm_sec += other_local_delta;
/* mktime will normalize the seconds to a correct calendar date */
other_t_synt = mktime(local_tm);
#endif
other_tm = localtime(&other_t_synt);
printf("Other time: %s", asctime(other_tm));
exit(0);
}
【讨论】:
如果你知道偏移量,你可以使用 gmtime() 和 tm 结构直接设置它。
如果您知道您的本地时间和 UTC,您就知道您的本地偏移量。如果您还知道目标偏移量,只需设置适当的 tm_hour(如果您选择 23,也可能会翻转一天)。
有关一些示例代码,请参阅此gmtime reference page。它显示了基于时区偏移量的偏移量。
编辑:
作为对 cmets 的响应 - 您还可以让 mktime 为您处理移位,这使您可以通过转换回 time_t 来简化此操作。你可以使用类似的东西:
time_t currentTime;
tm * ptm;
time ( ¤tTime );
ptm = gmtime ( &rawtime );
ptm->tm_hour += hours_to_shift;
ptm->tm_minutes += minutes_to_shift; // Handle .5 hr timezones this way
time_t shiftedTime = mktime( ptm );
// If you want to go back to a tm structure:
tm * pShiftedTm = gmtime( &shiftedTime );
【讨论】:
您的操作系统很可能为此提供了一些支持。
在 unix 派生的操作系统中,您可能需要查看 asctime, asctime_r, ctime, ctime_r, difftime, gmtime, gmtime_r, localtime, localtime_r, mktime, timegm 的手册页。
【讨论】: