The original version of virTimeLocalOffsetFromUTC() (commit 1cddaea7aeca441b733c31990a3f139dd2d346f6) would fail for certain times of the day if daylight savings time was active. This could most easily be seen by uncommenting the TEST_LOCALOFFSET() cases that invlude a DST setting. After a lot of experimenting, I found that the way to solve it in almost all test cases is to set tm_isdst = -1 in the stuct tm prior to calling mktime(). Once this is done, the correct offset is returned for all test cases at all times except the two hours just after 00:00:00 Jan 1 UTC - during that time, any timezone that is *behind* UTC, and that is supposed to always be in DST will not have DST accounted for in its offset. I still do not know the source of this problem, but it appears to be either a bug in glibc, or my improper specification of a TZ setting, so I am leaving the offending tests listed in virtimetest.c, but disabling them for now. --- See https://www.redhat.com/archives/libvir-list/2014-May/msg00898.html for my earlier comments on this problem. src/util/virtime.c | 3 +++ tests/virtimetest.c | 24 +++++++++++++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/util/virtime.c b/src/util/virtime.c index 3a56400..c69dff1 100644 --- a/src/util/virtime.c +++ b/src/util/virtime.c @@ -377,6 +377,9 @@ virTimeLocalOffsetFromUTC(long *offset) return -1; } + /* tell mktime to figure out itself whether or not DST is in effect */ + gmtimeinfo.tm_isdst = -1; + /* mktime() also obeys current timezone rules */ if ((utc = mktime(&gmtimeinfo)) == (time_t)-1) { virReportSystemError(errno, "%s", diff --git a/tests/virtimetest.c b/tests/virtimetest.c index bf27682..35551ea 100644 --- a/tests/virtimetest.c +++ b/tests/virtimetest.c @@ -161,20 +161,30 @@ mymain(void) TEST_LOCALOFFSET("VIR00:30", -30 * 60); TEST_LOCALOFFSET("VIR01:30", -90 * 60); + TEST_LOCALOFFSET("VIR05:00", (-5 * 60) * 60); TEST_LOCALOFFSET("UTC", 0); TEST_LOCALOFFSET("VIR-00:30", 30 * 60); TEST_LOCALOFFSET("VIR-01:30", 90 * 60); -#if __TEST_DST + /* test DST processing with timezones that always * have DST in effect; what's more, cover a zone with * with an unusual DST different than a usual one hour */ - /* NB: These tests fail at certain times of the day, so - * must be disabled until we figure out why - */ - TEST_LOCALOFFSET("VIR-00:30VID,0,365", 90 * 60); - TEST_LOCALOFFSET("VIR-02:30VID,0,365", 210 * 60); - TEST_LOCALOFFSET("VIR-02:30VID-04:30,0,365", 270 * 60); + TEST_LOCALOFFSET("VIR-00:30VID,0/00:00:00,366/23:59:59", + ((1 * 60) + 30) * 60); + TEST_LOCALOFFSET("VIR-02:30VID,0/00:00:00,366/23:59:59", + ((3 * 60) + 30) * 60); + TEST_LOCALOFFSET("VIR-02:30VID-04:30,0/00:00:00,366/23:59:59", + ((4 * 60) + 30) * 60); + TEST_LOCALOFFSET("VIR-12:00VID-13:00,0/00:00:00,366/23:59:59", + ((13 * 60) + 0) * 60); +#ifdef __BROKEN_DST_TESTS + TEST_LOCALOFFSET("VIR02:45VID00:45,0/00:00:00,366/23:59:59", + -45 * 60); + TEST_LOCALOFFSET("VIR05:00VID04:00,0/00:00:00,366/23:59:59", + ((-4 * 60) + 0) * 60); + TEST_LOCALOFFSET("VIR11:00VID10:00,0/00:00:00,366/23:59:59", + ((-10 * 60) + 0) * 60); #endif return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; -- 1.9.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list