C API返回在指定的时区TIMESTRING? [英] C API to return timestring in specified time zone?

查看:428
本文介绍了C API返回在指定的时区TIMESTRING?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C,有它转换时间由返回的任何API时间()功能到一个特定的时区?
有一个函数的strftime()可转换成系统的当前时区。
但我想要的是功能输入时间(返回时间())和时区,并会在所述时区格式的具体格式转换时间

In C, there is any API which converts time returned by time() function to a specific timezone? There is a function strftime() which converts into current timezone of the system. But what I want is function input is time (returned by time()) and timeZone and it will convert the specific formatted time in said timezone format.

有没有这样的API?

推荐答案

POSIX指定<一个href=\"http://pubs.opengroup.org/onlinepubs/9699919799/functions/tzset.html\"><$c$c>tzset():

POSIX specifies tzset():

tzset()功能应使用环境变量TZ的值来设置由的ctime ,本地时间 mktime 的strftime 。如果TZ不存在从环境,应使用实现定义的默认时区信息。

The tzset() function shall use the value of the environment variable TZ to set time conversion information used by ctime, localtime, mktime, and strftime. If TZ is absent from the environment, implementation-defined default timezone information shall be used.

所以,理论上你可以使用这样的事情 T0 (A time_t的)到美国/东部转换时候,是不是您的默认TZ:

So, you could in theory use something like this to convert t0 (a time_t) into US/Eastern time when that is not your default TZ:

char old_tz[64];
strcpy(old_tz, getenv("TZ"));
setenv("TZ", "EST5", 1);
tzset();
struct tm *lt = localtime(&t0);
char buffer[64];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", lt);
setenv("TZ", old_tz, 1);
tzset();

这preserves旧的时区的副本(你不能依靠它不改变或走出去的范围,当你这个东西裁切),然后设置在环境中的目标时区。然后,它告诉系统来看待$ TZ,并相应设置本地时区。然后,给定的 time_t的值转换为一个细分的本地时间本地时间(),格式化字符串,然后复位TZ环境变量,告诉系统再来看看它与 tzset()试。

This preserves a copy of the old time zone (you can't rely on it not changing or going out of scope while you're dinking with this stuff), then sets the target time zone in the environment. It then tells the system to look at $TZ and set the local time zone accordingly. You then convert the given time_t value to a broken down local time with localtime(), format the string, then reset the TZ environment variable and tell the system to take another look at it with tzset() again.

在实践中,这可以或可以不工作;这取决于系统。

In practice, this may or may not work; it depends on the system.

如果您需要这方面的东西线程安全的版本,你必须更加努力地工作。这是断然书面不是线程安全的。

If you need thread-safe versions of this stuff, you'll have to work harder. This is categorically not thread-safe as written.

样品code有skimped的错误检查与MDASH;它不具有任何

The sample code has skimped on error checking — it doesn't have any.

我绝不会声称这是做一个简单的方法;应该有一个更好的办法。

I would never claim this is a simple way of doing it; there ought to be a better way.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

static void time_convert(time_t t0, char const *tz_value)
{
    char old_tz[64];
    strcpy(old_tz, getenv("TZ"));
    setenv("TZ", tz_value, 1);
    tzset();
    char new_tz[64];
    strcpy(new_tz, getenv("TZ"));
    char buffer[64];
    struct tm *lt = localtime(&t0);
    strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", lt);
    setenv("TZ", old_tz, 1);
    tzset();
    printf("%ld = %s (TZ=%s)\n", (long)t0, buffer, new_tz);
}

int main(void)
{
    time_t t0 = time(0);
    char *tz = getenv("TZ");
    time_convert(t0, tz);
    time_convert(t0, "UTC0");
    time_convert(t0, "IST-5:30");
    time_convert(t0, "EST5");
    time_convert(t0, "EST5EDT");
    time_convert(t0, "PST8");
    time_convert(t0, "PST8PDT");
}

测试输出

1335761328 = 2012-04-29 23:48:48 (TZ=CST6CDT)
1335761328 = 2012-04-30 04:48:48 (TZ=UTC0)
1335761328 = 2012-04-30 10:18:48 (TZ=IST-5:30)
1335761328 = 2012-04-29 23:48:48 (TZ=EST5)
1335761328 = 2012-04-30 00:48:48 (TZ=EST5EDT)
1335761328 = 2012-04-29 20:48:48 (TZ=PST8)
1335761328 = 2012-04-29 21:48:48 (TZ=PST8PDT)

请注意,当对EST和PST字符串指定夏令code没有这样做,你会得到一个时区偏移;当有夏令code组(如EST5EDTPST8PDT)和时间要打印在今年适当的时候(如四月底),你得到的EDT或PDT时间值打印出来。

Note that when the strings for EST and PST do not have a daylight saving code specified, you get one time zone offset; when there is a daylight saving code set (such as "EST5EDT" or "PST8PDT") and the time to be printed is at the appropriate time of year (such as end of April), you get the EDT or PDT time value printed.

请注意,也有关于如何处理时区冲突的ISO标准。 ISO 8601(日期/时间格式化)说,东UTC(格林威治)的时区是积极的,UTC的那些东西都不利。至少一些其它标准(例如SQL中,ISO 9075)使用相同的表示法。另一方面,POSIX(即ISO 9945)使用中的TZ相反惯例,如示例中所示code。冲突是只接受长期precedent的感觉。 C标准是对TZ环境变量的格式(或有)沉默(虽然C99§7.23.3.5的的strftime 函数的做参考ISO 8601多次)。

Note, too, that there are conflicting ISO standards on how to handle time zones. ISO 8601 (for date/time formatting) says that time zones east of UTC (Greenwich) are positive and those west of UTC are negative. At least some other standards (e.g. SQL, ISO 9075) use the same notation. On the other hand, POSIX (aka ISO 9945) uses the opposite convention in TZ, as shown in the example code. The conflict is accepted only because of long-standing precedent. The C standard is silent on the format (or existence) of the TZ environment variable (though C99 §7.23.3.5 The strftime function does reference ISO 8601 a number of times).

和(只是作为一个有益的提醒,为什么错误检查是一个好主意),在Mac OS X 10.7.3,我的环境中没有它TZ集(但它通常是美国/太平洋,又名库比提诺,又名美洲/洛杉矶,时间)。因此,code以上时崩溃的getenv()返回一个空指针。我在环境 TZ = CST6CDT 运行它,你可以从输出的第一行看到的。

And (just as a salutary reminder why error checking is a good idea), on Mac OS X 10.7.3, my environment doesn't have TZ set in it (but it is normally US/Pacific, aka Cupertino, aka America/Los_Angeles, time). So the code above crashes when getenv() returns a null pointer. I ran it with TZ=CST6CDT in the environment, as you can see from the first line of output.

这篇关于C API返回在指定的时区TIMESTRING?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆