How to smartly convert a number of seconds in a date
In my embedded Linux application I have a "tick count" counter that increases 1 each 10 nanoseconds counting from 1st January 00:00:00 of 2014.
I want to be able to, picking the current value of the "tick count" counter, print it as the current date-time (year, month, day, hour, minute, second and millisecond) of my system already considering things such as leap year, February having 28/29 days, etc. and this using pure C methods (from time.h etc.).
But I don't know how to do it... For now I have the equivalent value in seconds, so I know how many seconds since the start date-time have passed, but not how to go from that to the current date-time value with everything adjusted, only in Qt which is not available (and the internet wasn't much of a help in this case till what could I understood of the explanations in cplusplus.com and etc.)
Any help appreciated.
Use gmtime()
.
Simply divide the tick count to get the whole number of seconds and add an offset to change the epoch from Jan 1, 2014 to Jan 1, 1970.
void print_time(unsigned long long tick_count) {
static const unsigned long ticks_per_sec = 100000000L;
static const time_t epoch_delta = 16071L*24*60*60;
time_t seconds = tick_count/ticks_per_sec + epoch_delta;
unsigned long fraction = tick_count%ticks_per_sec;
struct tm tm = *gmtime(&seconds);
printf("%4d-%02d-%02d %02d:%02d:%02d.%03lun",
tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec,
fraction/10000);
}
[After Accept Edit]
OP comments "I tried to use the methods from time.h and I was unsuccessful as well as that it considers the count of time since 1970, which is not my situation"
Another approach is to use mktime()
. This is less dependent on issues brought up by @DavidEisenstat. It relies on the tm_sec
field being an int
of sufficient width (like 32 bits) to cover years 2014 to 2082. mktime()
takes out-of-range fields and adjusts them to the expected ranges. Should tm_sec
be 16-bit, some simple adjustments could be had to tm_mday, tm_hour, tm_min, tm_sec
instead.
void print_time2(unsigned long long tick_count) {
static const unsigned long ticks_per_sec = 100000000L;
unsigned long fraction = tick_count%ticks_per_sec;
unsigned long long secondsFromJan12014 = tick_count/ticks_per_sec;
struct tm tm = {0};
tm.tm_year = 2014 - 1900;
tm.tm_mday = 1;
tm.tm_sec = secondsFromJan12014;
if (mktime(&tm) == (time_t)(-1)) Handle_Failure();
printf("%4d-%02d-%02d %02d:%02d:%02d.%03lun",
tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec,
fraction/10000);
}
First, converting nanoseconds to seconds are trivial. Second, adding the right number of seconds since the right epoch 1970-01-01 you will have to know how many seconds there were from the epoch UTC 2014-01-01 00:00:00. The date command at the Linux prompt will tell you this:
date -u -d "2014-01-01 00:00" +%s 1388534400
So you will simply have to do something like:
time_t current = 1388534400+my_10_nano_time_function()/100000000;
Once you have your correct time_t value you can use all functions like localtime, gmtime and strftime.
However, as time_t is in seconds you will have to calculates the milliseconds yourself, something like:
(my_10_nano_time_function()%/100000000)/100000
上一篇: Timespan包含飞跃
下一篇: 如何巧妙地转换日期中的秒数