2

I would like to create a function that will fill a struct with the current date and time, such as:

typedef struct DateAndTime
{
    int year;
    int month;
    int day;
    int hour;
    int minutes;
    int seconds;
    int msec;
}DateAndTime;

I know I can use localtime() from time.h, but the problem is that it gives me only time in seconds, and I want to get it also in milliseconds resolution. I know I might be able to use also gettimeofday() for this, but how can i combine those to get the above struct filled? Or maybe other function that gives milliseconds resolution?

How can i achieve this?

Note: My system is linux based.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
A. Sarid
  • 3,916
  • 2
  • 31
  • 56

2 Answers2

3

You could simply use gettimeofday() to obtain the seconds and micro seconds, and then use the seconds to call localtime(). You then can fill your structure as you wish.

Line this

#include <sys/time.h>
#include <time.h>
#include <stdio.h>

typedef struct DateAndTime {
    int year;
    int month;
    int day;
    int hour;
    int minutes;
    int seconds;
    int msec;
} DateAndTime;

int
main(void)
{
    DateAndTime date_and_time;
    struct timeval tv;
    struct tm *tm;

    gettimeofday(&tv, NULL);

    tm = localtime(&tv.tv_sec);

    // Add 1900 to get the right year value
    // read the manual page for localtime()
    date_and_time.year = tm->tm_year + 1900;
    // Months are 0 based in struct tm
    date_and_time.month = tm->tm_mon + 1;
    date_and_time.day = tm->tm_mday;
    date_and_time.hour = tm->tm_hour;
    date_and_time.minutes = tm->tm_min;
    date_and_time.seconds = tm->tm_sec;
    date_and_time.msec = (int) (tv.tv_usec / 1000);

    fprintf(stdout, "%02d:%02d:%02d.%03d %02d-%02d-%04d\n",
        date_and_time.hour,
        date_and_time.minutes,
        date_and_time.seconds,
        date_and_time.msec,
        date_and_time.day,
        date_and_time.month,
        date_and_time.year
    );
    return 0;
}
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
  • Simple as it can be. Thank you for this solution and code! – A. Sarid Aug 30 '16 at 14:49
  • 1
    Use `.%03d` else 1 millisecond will print out as `.1`. – chux - Reinstate Monica Aug 30 '16 at 15:58
  • 2
    Pedantic: `gettimeofday()` is _usually_ not found on systems with 16-bit `int` and `.tv_usec` is of type `suseconds_t` (signed integer type capable of storing values at least in the range [-1, 1000000].) IAC, suggest casting to `int` _after_ the division. `date_and_time.msec = (int) (tv.tv_usec / 1000;)` to cope with 16-bit `int`. UV anyways. – chux - Reinstate Monica Aug 30 '16 at 19:00
1

You can feed localtime with the time_t object returned as a part ofstruct timeval by the gettimeofday:

int gettimeofday(struct timeval *tv, struct timezone *tz);

struct timeval {
    time_t      tv_sec;     /* seconds */
    suseconds_t tv_usec;    /* microseconds */
};
Eugene Sh.
  • 17,802
  • 8
  • 40
  • 61