Lazer
Lazer

Reputation: 94810

How should I store a time_t timestamp to a file using C?

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?

Upvotes: 10

Views: 7860

Answers (3)

mu is too short
mu is too short

Reputation: 434635

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);

Upvotes: 16

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215201

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.

Upvotes: 3

pmg
pmg

Reputation: 108978

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 :-)

Upvotes: 1

Related Questions