开发者

How do I convert an ISO 8601 string to time_t in C++?

Does anyone know how to go from an ISO-8601-formatted date开发者_如何转开发/time string to a time_t? I am using C++ and it needs to work on Windows and Mac.

I have written the code but I am sure there is a version that is more "standard."

I will get a date like 2011-03-21 20:25 and I have to tell if the time is in the past or the future.


One ugly hack I thought would be fun: since you only want to determine which date/time is bigger, you can convert the date to string and compare strings. ;-) (The upside is you do not need strptime which is not available everywhere.)

#include <string.h>
#include <time.h>

int main(int argc, char *argv[])
{
    const char *str = "2011-03-21 20:25";
    char nowbuf[100];
    time_t now = time(0);
    struct tm *nowtm;
    nowtm = localtime(&now);
    strftime(nowbuf, sizeof(nowbuf), "%Y-%m-%d %H:%M", nowtm);
    if (strncmp(str, nowbuf, strlen(str)) >= 0) puts("future"); else puts("past");
    return 0;
}


You can use strptime to convert from a string to a struct tm, and then you can use mktime to convert from a struct tm to a time_t. For example:

// Error checking omitted for expository purposes
const char *timestr = "2011-03-21 20:25";
struct tm t;
strptime(timestr, "%Y-%m-%d %H:%M", &t);
time_t t2 = mktime(&t);
// Now compare t2 with time(NULL) etc.


If the timestamp is in the local timezone the following method converts from ISO8601 to UTC. Also it is not ignoring potential daylight saving. It is standard C99.

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

time_t from_iso8601_utc(const char* dateStr)
{
    struct tm t;
    int success = sscanf(dateStr, "%d-%d-%dT%d:%dZ", /* */
                         &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min);
    if (success != 5) {
        return 0;
    }

    /* compensate expected ranges */
    t.tm_year = t.tm_year - 1900;
    t.tm_mon = t.tm_mon - 1;
    t.tm_sec = 0;
    t.tm_wday = 0;
    t.tm_yday = 0;
    t.tm_isdst = 0;

    time_t localTime = mktime(&t);
    time_t utcTime = localTime - timezone;
    return utcTime;
}


Inspired from @Peter Kofler answer for 2022-12-13T17:15:53.499Z kind of dates:

int64_t dateTime_parse(char *dateString)
{
  char *format = "%d-%d-%dT%d:%d:%d.%dZ";
  
  struct tm t{};
  int msec;
  int parseCount = sscanf(dateString, format, &t.tm_year, &t.tm_mon, 
                          &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec, &msec);
  if (parseCount < 7)
  {
    return - 1;
  }
  t.tm_year -= 1900;
  t.tm_mon -= 1;
  t.tm_isdst = -1;               //let mktime figure out DST

  int64_t result = mktime(&t);   //this is time_t type
  result *= 1000;
  result += msec;

  return result;
}

Note that mktime assumes first parameter to be a pointer to local time. If you want the date string to be parsed as UTC, use _mkgmtime instead (in windows).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜