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

链接地址: http://www.djcxy.com/p/18538.html

上一篇: Timespan包含飞跃

下一篇: 如何巧妙地转换日期中的秒数