gpt4 book ai didi

c - 我正在尝试在 C 中构建 RFC3339 时间戳。如何获取时区偏移量?

转载 作者:太空宇宙 更新时间:2023-11-04 04:18:49 24 4
gpt4 key购买 nike

我正在尝试将一个 RFC3339 时间戳放在一起,它将用于将某个条目写入数据库。这将被格式化为,例如,2004-10-19 10:23:54+02,其中 +02 是与 GMT 的小时偏移量。事实证明这个偏移量很麻烦——我似乎无法在 C 中推导出这个值。

这是我正在使用的代码。当我尝试构建时,它说 tm 结构没有名为 tm_gmtoff 的成员:

#include <time.h>
#include <stdio.h>
int main(void)
{
time_t now = time(NULL);
struct tm *tm;
int off_sign;
int off;
if ((tm = localtime(&now)) == NULL) {
return -1;
}
off_sign = '+';
off = (int) tm->tm_gmtoff;
if (tm->tm_gmtoff < 0) {
off_sign = '-';
off = -off;
}
printf("%d-%d-%dT%02d:%02d:%02d%c%02d:%02d",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec,
off_sign, off / 3600, off % 3600);
return 0;

最佳答案

to build an RFC3339 timestamp in C

如果目标是 string,简单的解决方案是使用 strftime()

  time_t now;
time(&now);
struct tm *p = localtime(&now);
char buf[100];
size_t len = strftime(buf, sizeof buf - 1, "%FT%T%z", p);
// move last 2 digits
if (len > 1) {
char minute[] = { buf[len-2], buf[len-1], '\0' };
sprintf(buf + len - 2, ":%s", minute);
}
printf("\"%s\"\n", buf);

输出

"2018-11-21T13:21:08-06:00"

How do I get the timezone offset?
When I try to build, it says the tm struct doesn't have a member named tm_gmtoff:

tm_gmtoffstruct tm 的可选额外成员。如果可用,该成员或其他一些类似的依赖于实现的成员将很好用。


根据@jwdonahue 的建议,可以访问strftime()"%z" .
"%z" 从 C99 开始可用。

%z is replaced by the offset from UTC in the ISO 8601 format ‘‘−0430’’ (meaning 4hours 30 minutes behind UTC, west of Greenwich), or by no characters if no timezone is determinable. C11 §7.27.3.5 3

int main(void) {
time_t now;
time(&now);
struct tm *p = localtime(&now);
char buf[6];
strftime(buf, sizeof buf, "%z", p);
int h, m;
sscanf(buf, "%3d%d", &h, &m);
if (h < 0) m = -m;
printf("Minute difference %d\n", h*60+m);
}

CT 的输出

Minute difference -360

缺少上述选择,代码可以直接从 localtime()gmttime() 中推断出时区偏移量:做一个 struct tm 减法.

以下利用时间戳的差异在 1 月 1 日附近不超过 1 天。

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

// Return difference in seconds.
long tz_offset(time_t t) {
struct tm *p = localtime(&t);
if (p == NULL) return INT_MIN;
printf("%s", asctime(p));
struct tm local = *p;
p = gmtime(&t);
if (p == NULL) return INT_MIN;
printf("%s", asctime(p));
struct tm gmt = *p;

int day = local.tm_yday - gmt.tm_yday;
if (local.tm_year > gmt.tm_year) {
day = 1;
} else if (local.tm_year < gmt.tm_year) {
day = -1;
}
int hour = day*24 + (local.tm_hour - gmt.tm_hour);
if (local.tm_isdst) {
; // no adjustment
}
long diff = (hour*60L + (local.tm_min - gmt.tm_min))*60 + (local.tm_sec - gmt.tm_sec);
return diff;
}

int main(void) {
time_t now;
time(&now);
printf("tz offset %g\n", tz_offset(now)/3600.0);

// Check time 6-months from now, maybe different daylight setting
struct tm *p = localtime(&now);
p->tm_mon += 6;
now = mktime(p);
printf("tz offset %g\n", tz_offset(now)/3600.0);
return 0;
}

CT 的示例输出

Tue Feb 13 11:40:00 2018
Tue Feb 13 17:40:00 2018
tz offset -6
Mon Aug 13 12:40:00 2018
Mon Aug 13 17:40:00 2018
tz offset -5

根据 RFC3339 打印时区偏移量给定小时,分钟:

  // Alway print the sign and leading zero digits
printf("%+02d:%02d", hours, abs(minute));

另见 What's the difference between ISO 8601 and RFC 3339 Date Formats?

关于c - 我正在尝试在 C 中构建 RFC3339 时间戳。如何获取时区偏移量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48771851/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com