8

For a small todo program that I am writing, I have timestamps that are of this form

time_t t = time(NULL);

and are saved every time a task is entered to denote the time that it was entered.

I want to store the tasks to a plain text file, so that the state can be saved and restored. How should I store the timestamps to the text file and how should I get them back in my program after reading the text file?

Lazer
  • 90,700
  • 113
  • 281
  • 364

3 Answers3

15

Convert the time_t to struct tm using gmtime(), then convert the struct tm to plain text (preferably ISO 8601 format) using strftime(). The result will be portable, human readable, and machine readable.

To get back to the time_t, you just parse the string back into a struct tm and use mktime().

For reference:

Code sample:

// Converting from time_t to string
time_t t = time(NULL);
struct tm *ptm = gmtime(&t);
char buf[256];
strftime(buf, sizeof buf, "%F %T", ptm);
// buf is now "2015-05-15 22:55:13"

// Converting from string to time_t
char *buf = "2015-05-15 22:55:13";
struct tm tm;
strptime(buf, "%F %T", &tm);
time_t t = mktime(&tm);
congusbongus
  • 13,359
  • 7
  • 71
  • 99
mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • @simpleBob: There are only three function calls and they're all well documented at the provided links. Have you tried using them? Did you run into any specific problems? – mu is too short Nov 19 '13 at 18:48
  • I was just wondering how to get encode it back to time_t after using `strftime()`. But I found `strptime` already. Thank you! – Daniel Nov 20 '13 at 08:32
3

The portable way is using the difftime function. Compute the time_t for a chosen epoch using mktime, then use difftime to compute the difference in seconds. To convert back, you can start with the epoch as a struct tm and add the number of seconds to tm_sec, then call mktime to get a time_t.

The sane way is to assume time_t is represented as seconds since the Unix epoch (1970-01-01 00:00 GMT) and convert to a large integer type (long long is best) to print it. POSIX requires time_t to be seconds since the epoch, and on any sane system it will be.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
1

If you don't mind a bit of unportable assumptions, just cast time_t to long (long long if you have a C99 compiler), write the long value, read the value and cast back to time_t.

The Standard makes no guarantee that a time_t is even representable as a long: it only says time_t is a arithmetic type, but the trick above should work for all sane systems :-)

pmg
  • 106,608
  • 13
  • 126
  • 198