Yes,we can do that but the only issue is that gettimeofday() refers to the current local time for giving us milliseconds since epoch. |
Yes, you're right.
There are a couple of extensions to struct tm that can help. They're not described by Posix, but they're been around for ever and are available in Linux and BSD.
This is from my local Linux box:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
/* ISO C `broken-down time' structure. */
struct tm
{
int tm_sec; /* Seconds. [0-60] (1 leap second) */
int tm_min; /* Minutes. [0-59] */
int tm_hour; /* Hours. [0-23] */
int tm_mday; /* Day. [1-31] */
int tm_mon; /* Month. [0-11] */
int tm_year; /* Year - 1900. */
int tm_wday; /* Day of week. [0-6] */
int tm_yday; /* Days in year.[0-365] */
int tm_isdst; /* DST. [-1/0/1]*/
# ifdef __USE_MISC
long int tm_gmtoff; /* Seconds east of UTC. */
const char *tm_zone; /* Timezone abbreviation. */
# else
long int __tm_gmtoff; /* Seconds east of UTC. */
const char *__tm_zone; /* Timezone abbreviation. */
# endif
};
|
And from 4.3 BSD (reno):
1 2 3 4 5 6 7 8 9 10 11 12 13
|
struct tm {
int tm_sec; /* seconds after the minute [0-60] */
int tm_min; /* minutes after the hour [0-59] */
int tm_hour; /* hours since midnight [0-23] */
int tm_mday; /* day of the month [1-31] */
int tm_mon; /* months since January [0-11] */
int tm_year; /* years since 1900 */
int tm_wday; /* days since Sunday [0-6] */
int tm_yday; /* days since January 1 [0-365] */
int tm_isdst; /* Daylight Savings Time flag */
long tm_gmtoff; /* offset from CUT in seconds */
char *tm_zone; /* timezone abbreviation */
};
|
tm_gmtoff
is the number of seconds you need to add to get you back to GMT/UTC.
For example, for EST, tm_gmtoff = -18000, and for BST tm_gmtoff = 3600.
So, putting it all together:
1. call gettimeofday() to get the localtime in seconds.microsec
2. call localtime to fill in a struct tm
3. check tm_isdst, if it's set, add tm_gmtoff from the struct timeval.
This C program demonstrates the idea:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
#include <sys/time.h>
#include <time.h>
#include <stdio.h>
struct timeval get_gmtime() {
struct timeval tv;
struct tm tm;
gettimeofday(&tv, NULL);
localtime_r(&tv.tv_sec, &tm);
if (tm.tm_isdst)
tv.tv_sec += tm.tm_gmtoff;
return tv;
}
int main() {
struct timeval tv = get_gmtime();
printf("now: %ld.%06ld\n", tv.tv_sec, tv.tv_usec);
return 0;
}
|
EDIT
I say add gmtoff, but it might be subtract. I haven't thought it thru fully. Please double check.