我没有找到一种简单的方法来获得当地时间和UTC时间之间的分钟数.
起初我打算使用,tzset()但它不提供夏令时.根据手册页,如果日光节省有效,它只是一个不等于零的整数.虽然通常是一个小时,但在某些国家可能需要半小时.
我宁愿避免计算当前UTC返回的时间差gmtime()和localtime().
更通用的解决方案将为我提供指定位置和正time_t值的信息,或至少在本地.
编辑1:用例是为https://github.com/chmike/timez获取正确的本地时间偏移量.顺便说一句,如果您认为libc函数操作时间还可以,请阅读https://rachelbythebay.com/w/2013/03/17/time/.
编辑2:迄今为止我用来计算UTC时间偏移的最佳和最简单的解决方案是
// Bogus: assumes DST is always one hour
tzset();
int offset = (int)(-timezone / 60 + (daylight ? 60 : 0));
Run Code Online (Sandbox Code Playgroud)
问题是确定实际的节省时间.
编辑3:受到@trenki答案的启发,我提出了以下解决方案.这是一个黑客,因为它mktime()可以将输出gmtime()视为本地时间.当DST更改在UTC时间和本地时间之间的时间跨度时,结果是不准确的.
#include <stdio.h>
#include <time.h>
int main()
{
time_t rawtime = time(NULL);
struct tm *ptm = gmtime(&rawtime);
// Request that mktime() looksup dst in timezone database
ptm->tm_isdst = -1;
time_t gmt = mktime(ptm);
double offset = difftime(rawtime, gmt) / 60;
printf("%f\n", offset);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此C代码以分钟为单位计算相对于UTC的本地时间偏移。假定DST总是偏移一小时。
#include <stdio.h>
#include <time.h>
int main()
{
time_t rawtime = time(NULL);
struct tm *ptm = gmtime(&rawtime);
time_t gmt = mktime(ptm);
ptm = localtime(&rawtime);
time_t offset = rawtime - gmt + (ptm->tm_isdst ? 3600 : 0);
printf("%i\n", (int)offset);
}
Run Code Online (Sandbox Code Playgroud)
虽然它使用gmtime和localtime。您为什么不想使用这些功能?
我想对这个问题提交另一个答案,即 AFAICS 也涉及 IDL。
该解决方案取决于timegm和mktime。在 Windows 上timegm可从 CRT 获取_mkgmtime,换句话说,定义一个条件宏。
#if _WIN32
# define timegm _mkgmtime
#endif
int local_utc_offset_minutes ( ) {
time_t t = time ( NULL );
struct tm * locg = localtime ( &t );
struct tm locl;
memcpy ( &locl, locg, sizeof ( struct tm ) );
return (int)( timegm ( locg ) - mktime ( &locl ) ) / 60;
}
Run Code Online (Sandbox Code Playgroud)