#if 0 /* -*- mode: c; c-file-style: "stroustrup"; tab-width: 8; -*- set -eu; trg=`basename "$0" .c`; rm -f "$trg" WARN="-Wall -Wno-long-long -Wstrict-prototypes -pedantic" WARN="$WARN -Wcast-align -Wpointer-arith " # -Wfloat-equal #-Werror WARN="$WARN -W -Wwrite-strings -Wcast-qual -Wshadow" # -Wconversion case ${1-} in '') set x -O2; shift; esac #case ${1-} in '') set x -ggdb; shift; esac set -x; exec ${CC:-gcc} -std=c99 $WARN "$@" -o "$trg" "$0" exit $? */ #endif /* * $ xtimegm.c $ * * Author: Tomi Ollila -- too ät iki piste fi * * Created: Mon 05 Nov 2012 07:54:35 EET too * Last modified: Mon 05 Nov 2012 08:27:52 EET too * * Public domain. */ #define _POSIX_SOURCE #include time_t xtimegm(struct tm * atm) { struct tm ltm; time_t t = mktime(atm); int sd; int dd; (void)gmtime_r(&t, <m); sd = (atm->tm_hour - ltm.tm_hour) * 3600 + (atm->tm_min - ltm.tm_min) * 60 + (atm->tm_sec - ltm.tm_sec); dd = (atm->tm_mday - ltm.tm_mday); if (dd == 0) ; else if (dd == -1) sd -= 86400; /* e.g. 3, 2 */ else if (dd == 1) sd += 86400; /* e.g. 2, 3 */ else if (dd > 1) sd -= 86400; /* e.g. 1, 31 */ else /* dd < 1 */ sd += 86400; /* e.g. 31, 1 */ printf("sd: %d\n", sd); // test line. return t + sd; } #include void test(int hour, int mday) { struct tm mtm; time_t t; struct tm * otm; mtm.tm_sec = 0; mtm.tm_min = 0; mtm.tm_hour = hour; mtm.tm_mday = mday; mtm.tm_mon = 11; mtm.tm_year = 100; mtm.tm_isdst = -1; t = xtimegm(&mtm); otm = gmtime(&t); printf("%2d %02d:%02d:%02d\n", otm->tm_mday, otm->tm_hour, otm->tm_min, otm->tm_sec); } void tests(const char * tz) { printf("TZ: %s\n", tz); setenv("TZ", tz, 1); tzset(); test(23, 30); test(23, 31); test(23, 1); test(23, 2); printf("--\n"); test(1, 30); test(1, 31); test(1, 1); test(1, 2); } int main(int argc, char * argv[]) { // ls /usr/share/zoneinfo... tests("EET"); tests("MST"); tests("HST"); tests("NZ"); return 0; }