I wrote a small function to convert Date & Time in UTC to UNIX time (Epoch time). The value that I get, however, is dependent on the time-zone I am in.
Here is the code
#include<stdio.h>
#include<time.h>
time_t GenerateUnixTimeStampFromDateAndTime(char *DateAndTime);
void main()
{
long int UnixTime=0;
char *CurrentTime="01/22/2019 06:30:00";
UnixTime = (long int)GenerateUnixTimeStampFromDateAndTime(CurrentTime);
printf("Current Unix Time= %ld\r\n", UnixTime);
}
time_t GenerateUnixTimeStampFromDateAndTime(char *DateAndTime)
{
struct tm ti={0};
if( sscanf(DateAndTime, "%d/%d/%d %d:%d:%d", &ti.tm_mon, &ti.tm_mday, &ti.tm_year, &ti.tm_hour, &ti.tm_min, &ti.tm_sec) != 6 )
return -1;
ti.tm_year = ti.tm_year - 1900;
ti.tm_mon = ti.tm_mon - 1;
return mktime(&ti);
}
The answer I get is 1548118800 which is 01/22/2019 01:00:00 ie -5:30 which is the time-zone I am in (India). If I change my PC timezone to UTC, then it gives correct value of 1548138600.
What changes do i need to make it time-zone independent?
As documented, mktime()
takes the broken-down time components in local time.
First, save the users current timezone:
char *old_timezone, *temp;
temp = getenv("TZ");
if (temp) {
const size_t len = temp;
old_timezone = malloc(len + 1);
if (!old_timezone) {
fprintf(stderr, "Out of memory!\n");
exit(EXIT_FAILURE);
}
if (len > 0)
memcpy(old_timezone, temp, len);
old_timezone[len] = '\0';
} else
old_timezone = NULL;
If the user uses the system default, old_timezone
will be NULL.
Next, set the current timezone (for this process) to UTC:
setenv("TZ", "UTC", 1);
tzset();
Note that if you want, you can use any timezone specifier instead of "UTC"
above; see tzset()
for details. The tzset()
call is usually done internally by your C library, but doing it explicitly here helps us humans see that something timezone-specific just occurred.
At this point, mktime()
will operate in UTC, and localtime()
and gmtime()
will return the same results.
Afterwards, restore the timezone by
if (old_timezone) {
setenv("TZ", old_timezone, 1);
free(old_timezone);
old_timezone = NULL;
} else
unsetenv("TZ");
tzset();
Note that this does not affect anything except the current process (and any child processes you might create via popen()
or system()
or fork()
and exec()
). Timezone, like locale, is a per-process property.
Running
unsetenv("TZ");
tzset();
will change the current timezone for this process to the system default timezone.
If your program operates explicitly in UTC, you can do just
/* This program works explicitly in the UTC timezone.
User/system timezone configuration is completely ignored. */
setenv("TZ", "UTC", 1");
tzset();
near the beginning of your main()
.