11

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.

Drew Noakes
  • 284,599
  • 158
  • 653
  • 723
reza
  • 5,444
  • 14
  • 71
  • 108
  • 2
    There's a similar discussion about a cross-platform `strptime` [here](http://stackoverflow.com/questions/321849/strptime-equivalent-on-windows). You may want ravenspoint's answer, and use boost: `#include "boost/date_time/posix_time/posix_time.hpp"` – Tim Mar 21 '11 at 21:23

3 Answers3

8

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;
}
Mormegil
  • 7,800
  • 3
  • 42
  • 75
  • 3
    While I instinctively cringe at such an idea... that is the point of the "YYYYMMDD HHMMSS" format - ascii comparisons actually work. The risk, of course is if he starts getting dates in a different format in the future. – Tim Mar 21 '11 at 21:19
7

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.
Mark Lakata
  • 19,008
  • 5
  • 97
  • 119
Adam Rosenfield
  • 375,615
  • 96
  • 501
  • 581
  • 2
    strptime isn't standard c. Will it be available on Windows? – Null Set Mar 21 '11 at 21:12
  • 1
    @Null Set: Oops you're right, forgot about that. `strptime` is only defined by POSIX. See http://stackoverflow.com/questions/321849/strptime-equivalent-on-windows and http://stackoverflow.com/questions/667250/strptime-in-windows . – Adam Rosenfield Mar 22 '11 at 18:32
0

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;
}
Peter Kofler
  • 9,058
  • 8
  • 50
  • 79