0%

iso8601 时间格式以及转换

iso8601与时间戳之间的转换

ISO8601

ISO8601是国际标准化组织的日期和时间的表示方法,常见如下

  • 日期
    • 2019-09-11
  • UTC 日期与时间
    • 2019-09-11T01:54:23+00:00
    • 2019-09-11T01:54:23Z
    • 20190911T015423Z
  • 周数
    • 2019-W37
  • 日期与周数
    • 2019-W37-3
  • 无年份标示之日期
    • --09-11[1]
  • 当年度累积日数
    • 2019-254

其中日期与时间合并表达时,需要在时间前加T
如果时间在零时区,并恰好与协调世界时相同,那么在时间最后加一个大写字母ZZ是相对协调世界时时间0偏移的代号。

UTC

UTC协调世界时是最主要的世界时间标准

影响时间转换的环境变量TZ

时间函数除了gmttimeasctime不受环境变量TZ的影响外,大部分函数都受到环境变量TZ的影响,这几个函数是:localtimemktimectimestrftime。如果定义了TZ,则这些函数将使用其值以代替系统默认时区。

API

ISO8601 to timestamp

char *strptime(const char *s, const char *format, struct tm *tm)将时间格式字符串S按指定格式foramt解析成tm;再用time_t mktime(struct tm *tm)函数将tm生成时间戳。

static time_t _iso8601_to_timestamp(const char *str)
{
    struct tm ttime = {0};

    if (!str) {
        return 0;
    }
    strptime(str, "%Y-%m-%dT%H:%M:%SZ", &ttime);
    return mktime(&ttime);
}

或者获取当前时间戳

time_t now;
time(&now);
printf("now:%ld",now);

timestamp to STRING

和时间操作相关的关键数据结构是struc tm,其定义如下:

struct tm {
    int tm_sec;    /* Seconds (0-60) */
    int tm_min;    /* Minutes (0-59) */
    int tm_hour;   /* Hours (0-23) */
    int tm_mday;   /* Day of the month (1-31) */
    int tm_mon;    /* Month (0-11) */
    int tm_year;   /* Year - 1900 */
    int tm_wday;   /* Day of the week (0-6, Sunday = 0) */
    int tm_yday;   /* Day in the year (0-365, 1 Jan = 0) */
    int tm_isdst;  /* Daylight saving time */
};

在将时间戳表示成指定格式前,我们需要将时间戳转换成 tm 数据结构。

  1. struct tm *gmtime(const time_t *timep)
  2. struct tm *localtime(const time_t *timep)

gtime转换后的tm是基于时区0的,而localtime转换后的是基于当地时区

利用接口 size_t strftime(char *s, size_t max, const char *format,const struct tm *tm) 来定制我们的时间格式

time_t t;
time(&t);
struct tm *tmp_time = localtime(&t);
char s[100];
strftime(s, sizeof(s), "%04Y%02m%02d %H:%M:%S", tmp_time);
printf("%d: %s\n", (int)t, s);

Ref

  1. UTC 和 ISO 8601 时间格式的一些疑问
  2. ISO 8601
  3. 时间日期与时间戳转换
  4. c 语言中的时间戳和时间格式