0

Is there any way to store number of time ticks from gettimeofday() and format into some specific way (for example "%m-%d-%Y %T") without using any array?.

This will save memory for each instance of a program which calculates current time.

Code for the same using an array.(Taken from C - gettimeofday for computing time?)

  char buffer[30];
  struct timeval tv;

  time_t curtime;



  gettimeofday(&tv, NULL); 
  curtime=tv.tv_sec;

  strftime(buffer,30,"%m-%d-%Y  %T.",localtime(&curtime));
 printf("%s%ld\n",buffer,tv.tv_usec);
  • "without using any array?" --> Certainly, save as a `struct tm`. OTOH, this may be _more_ memory than `buffer[30]` Or save in a structure `int8_t y,m,d, int16_t hms; int32_t ns;` Other packed formats can well stuff the `gettimeofday()` return value into 64-bits. It just depends on how much range and work you want vs memory. – chux - Reinstate Monica Jan 02 '18 at 06:28
  • Note that the `printf()` should use `"%s%.6ld"` where the `.6` is the crucial missing piece — it ensures that `tv_usec == 300` is formatted as `000300` and not as `300`; the latter gives completely the wrong information. – Jonathan Leffler Jan 02 '18 at 07:03
  • What is the problem you're trying to resolve? This feels like an [XY Problem](http://mywiki.wooledge.org/XyProblem). If you're going to format a time into a string, you are pretty much required to use a string somewhere along the line. You could, I suppose, choose `struct tm *tp = localtime(&curtime); printf("%02d-%02d-%04d %02d:%02d:%02d.%06d\n", tp->tm_mon + 1, tp->tm_mday, tp->tm_year + 1900, tp->tm_hour, tp->tm_min, tp->tm_sec, tv.tv_usec);` — but that gets painful if you want strings instead of numbers (e.g. month names) in the output. – Jonathan Leffler Jan 02 '18 at 07:08
  • 2
    Note that `localtime()` involves a time zone database that will consume many MB of memory, so worrying about a few bytes in local variables that will be freed/reused as soon as a function returns is relatively pointless. – Brendan Jan 02 '18 at 07:16
  • Exactly, the function stack doesn't care how many bytes you actually use from it -- as long as you do not overflow the stack. So worrying about 30 or 60 or 50000 bytes when 1M is generally available makes no sense. There is educational value in determining how small you can make something, but it has no practical value considering normal function stack size. – David C. Rankin Jan 02 '18 at 07:28
  • @Brendan Although OP's goal is a bit unclear, it is reasonable to consider that code will be saving many millions of timestamps and reducing that memory footprint makes sense. – chux - Reinstate Monica Jan 02 '18 at 15:35

1 Answers1

0

any way to store number ... from gettimeofday() and ... without using any array?

gettimeofday() does not return the "number of time ticks". It is a *nix functions defined to populate a struct timeval which contains a time_t and a long representing the current time in seconds and microseconds. Use clock() to get "number of time ticks".

The simplest way to avoid an array is to keep the result in a struct timeval without any modifications.


This will save memory for each instance of a program which calculates current time.

This sounds like OP would like to conserve memory as much as possible. Code could convert the struct timeval to a int64_t (a count of microseconds since the epoch) without much risk of range loss. This would only be a memory savings if sizeof(struct timeval) > sizeof(int64_t).

#include <sys/time.h>

int64_t timeval_to_int64(const struct timeval *tv) {
  const int32_t us_per_s = 1000000;
  int64_t t = tv->tv_sec;

  if (t >= INT64_MAX / us_per_s
      && (t > INT64_MAX / us_per_s || tv->tv_usec > INT64_MAX % us_per_s)) {
    // Handle overflow
    return INT64_MAX;
  }
  if (t <= INT64_MIN / us_per_s
      && (t < INT64_MIN / us_per_s || tv->tv_usec < INT64_MIN % us_per_s)) {
    // Handle underflow
    return INT64_MIN;
  }
  return t * us_per_s + tv->tv_usec;
}

void int64_to_timeval(struct timeval *tv, int64_t t) {
  const int32_t us_per_s = 1000000;
  tv->tv_sec = t / us_per_s;
  tv->tv_usec = t % us_per_s;
  if (tv->tv_usec < 0) {  // insure tv_usec member is positive.
    tv->tv_usec += us_per_s;
    tv->tv_sec++;
  }
}

If code wants to save the timestamp to a file as text, with minimal space, a number of choices are available. What is the most efficient binary to text encoding? goes over some ideas. For OP's code though a decimal or hexadecimal print of the 2 members may be sufficient.

printf("%lld.%06ld\n", (long long) tv.tv_sec, tv.tv_usec);

I do not recommend storing timestamps via localtime() as that imparts ambiguity or overhead of timezone and day light savings time. If code must saving using month, day, year, consider ISO 8601 and using universal time.

#include <sys/time.h>

int print_timeval_to_ISO8601(const struct timeval *tv) {
  struct tm t = *gmtime(&tv->tv_sec);
  return printf("%04d-%02d-%02dT%02d:%02d:%02d.%06ld\n", //
      t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, //
      t.tm_hour, t.tm_min, t.tm_sec, tv->tv_usec);

  // Or ("%04d%02d%02d%02d%02d%02d.%06ld\n"
}

Note OP's code has a weakness. Microsecond values like 12 will print a ".12" when ".000012" should appear.

// printf("%s%ld\n",buffer,tv.tv_usec);
printf("%s%06ld\n",buffer,tv.tv_usec);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256