Ìn general sending binary data is error-prone, due the possiblity of the different ways of its interpretation on the sender and the receiver side.
For time_t
in particular it isn't even clear how many bits would be involved, it may be 32 or 64 or even something much more complicated, as time_t
might even be implemented as a struct
.
In your special case using htonl()
, 32 bits are assumed, as htonl()
takes a 32 bit value.
So the fail-safe solution indeed is to send out a text representation of the system time.
Programmatically this might look like this:
char st[64] = "";
{
struct * tm = gmtime(time(NULL));
if (NULL == tm)
{
fprintf(stderr, "gmtime() failed\n");
}
{
if(0 == strftime(st, sizeof(st), "%s", tm)) /* Prints the text representaiotn of the seconds since Epoch into st. */
{
fprintf(stderr, "strftime() failed\n");
}
}
}
To reverse this operation you could use strptime()
:
char st[64] = "123456789123";
time_t t;
memset(&t, 0, sizeof(t));
{
struct tm = {0};
char p = strptime(t, "%s", &tm);
if (NULL == p || p != (t + strlen(t)))
{
fprintf(stderr, "strptime() failed\n");
}
else
{
t = mktime(&tm);
}
}
The nice thing using strptime()
and strftime()
is that you a can easily changed the format of the date/time in transit, by just modifying the format as specified when calling those two functions.
Changing "%s"
to "%Y-%m-%d %H:%M:%S"
would transfer the time like "2014-05-20 13:14:15"
.
However if you really want to send seconds since Epoch in binary format and stay fail-safe and portable you need to take care of three things:
- Get the number of seconds since Epoch in a portable way.
- Select an integer type definitly large enough.
- Convert this "large" value to network byte order.
A possible approach for this would be:
#include <time.h>
#include <inttypes.h> /* For uint64_t, as 64bit should do to represent the seconds since Epoch for the next few years. */
...
time_t t_epochbegin;
memset(&t_epochbegin, 0, sizeof(t_epochbegin);
uint64_t t_host = (uint64_t) difftime(time(NULL), t_epochbegin); /* Get the seconds since Epoch without relying on time_t being an integer. */
uint64_t t_network = htonll(t_host); /* Convert to network byte order. */
On how to implement the non-standard htonll()
see the various answers to this question: Big Endian and Little Endian support for byte ordering
All code in the examples above assumes the system the code runs on provides a timer and though calls to time()
wouldn't fail.