Calculating GMT offset of any timezone is a little bit tricky. I need to deal with this situation, in one of my project. I have written a small program.
I have considered /usr/share/zoneinfo as default timezone directory. You need to change if you timezone files are located any where else. Your feedback are valuable for me.
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#define ABS(ent) (ent) = ((ent)>0?(ent):0-(ent))
#define TZ_DIR "/usr/share/zoneinfo"
static void
display_gmt_off(long tz)
{
int32_t hrs, min;
hrs = tz/3600;
min = tz % 3600;
min = min/60;
ABS(min);
ABS(hrs);
fprintf(stdout, "(GMT");
if (tz < 0) {
fprintf(stdout, "+");
} else if (tz > 0) {
fprintf(stdout, "-");
}
if (hrs > 0 || min > 0) {
fprintf(stdout, "%d:%d", hrs, min);
}
fprintf(stdout, ")\n");
}
static int
invalid_timezone(const char *tz)
{
char tzpath[1024];
struct stat st;
snprintf(tzpath, sizeof(tzpath), "%s/%s", TZ_DIR, tz);
memset(&st, 0, sizeof(st));
return stat(tzpath, &st);
}
int
main(int argc, char **argv)
{
const char *tz;
if (argc != 2) {
fprintf(stderr, "Usage %s \n", basename(argv[0]));
return 1;
}
tz = argv[1];
if (invalid_timezone(tz)) {
fprintf(stderr, "Invalid timezone %s\n", tz);
return 1;
}
if (setenv("TZ", tz, 1) < 0) {
fprintf(stderr, "Cannot set TZ(%s)\n", tz);
return 1;
}
tzset();
display_gmt_off(timezone); /* extern variable in time.h */
return 0;
}