如何轻松地将时间和分钟添加到gmtime

时间:2013-04-10 15:18:32

标签: c linux time.h

是否有通过gmtime获得的time.h添加小时和分钟的预定义方法?我想编写一个程序来显示各个国家的时间,所以我必须自己编写逻辑还是有预定义的方法?

2 个答案:

答案 0 :(得分:3)

没有标准化的功能可以完成必要的工作。但是,您可以通过修改struct tm来相对简单地完成此操作。该结构拥有许多成员;一个小时,一个几分钟等等。一旦你更新了struct的成员,你应该调用mktime来规范化这些值。

例如,如果分钟已经设置为55而你加10,则它们将被设置为65.调用mktime会将分钟设置为5并相应地更新小时和其他成员。

作为示例,添加十分钟将如下所示:

struct tm *t = ...
t->tm_min += 10;
mktime(t);

答案 1 :(得分:3)

如果您有时区名称(例如Europe/HelsinkiUS/EasternMST),则可以使用非常简单的POSIX界面。

它确实为整个过程应用了时区,因此如果您使用线程,则需要包装日期/时间函数以避免并发日期/时间访问,除非它们使用相同的时区,例如使用互斥。此处显示的示例不是线程安全的,以使示例更易于理解。

首先,将环境变量TZ设置为以冒号为前缀的时区名称。这是POSIX系统中用于为各个进程设置时区(并影响进程中所有线程)的方法。例如,

setenv("TZ", ":Europe/Helsinki", 1);

设置赫尔辛基时区。有关详细信息,请参阅man 3 setenv。仅凭这还不够;您还必须通过调用

告诉C库更新当前时区
tzset();

然后,您可以检查全局变量tzname[0](应包含Europe)和tzname[1](应包含Helsinki)以查看实际设置的时区。有关详细信息,请参阅man 3 timezone;你可以,例如请使用POSIX时区定义语法来指定自定义时区。

在上面的两行之后,无论何时使用localtime()localtime_r(),都会应用所选的时区。就这么简单。


如果您还希望更改时间戳的格式以符合特定区域设置,则可以通过

设置区域设置(例如,设置为fi_FI.utf8
setlocale(LC_TIME, "fi_FI.utf8");

请注意,正如man 3 setlocale联机帮助页所述,区域设置必须采用规范格式,fi等简短格式不起作用。然后,使用例如

time_t     now_time;
struct tm *now_tm;
char      *format;
char       buffer[256];
size_t     length;

time(&now_time);
now_tm = localtime(&now_time);
if (!now_tm) {
    /* Error, cannot get local time corresponding to now_time! */
    return -1;
}

format = nl_langinfo(D_T_FMT);
if (!format || !*format) {
    /* Error, cannot get date-time formatting string for this locale */
    return -1;
}

/* Note: both now_tm and format point to static buffers,
 *       and they will be overwritten by subsequent calls.
*/

length = strftime(buffer, sizeof buffer, format, now_tm);
if (length < 1 || length >= sizeof buffer) {
    /* Error in locale configuration; cannot generate date-time string. */
    return -1;
}

此时buffer包含芬兰语中的日期和时间(或上次setlocale(LC_TIME, locale)调用中设置的任何区域设置),芬兰时区(或上次设置的任何时区{{1}调用)。

(最后setenv("TZ", ":Europe/Helsinki", 1); tzset();检查向后兼容一些非常旧的系统,如果缓冲区太小,则返回length。当缓冲区足够大时,较新的系统返回,但是我期望256个字节足以满足任何语言的时间和日期。)

我想指出这一点,因为在类似POSIX的系统中,语言环境(语言和格式)和时区完全是分开的。