Skip to content

LocalDateTime returns wrong tzd for Ireland/Dublin time zone. #3510

@radimdvorak

Description

@radimdvorak

LocalDateTime class returns wrong time zone differential for Ireland/Dublin time zone during winter time.

TZD returned by LocalDateTime is 7200 but std::tm::tm_gmtoff value is 0 during winter time. The issue is from my point of view relying on DST being always positive but Ireland has special Winter time - see Wikipedia where daylight saving time is used in winter and goes 1 hour back in time.

Simple test can be made to test it on Linux:

setenv("TZ", "/usr/share/zoneinfo/Europe/Dublin", 1); // POSIX-specific
Poco::LocalDateTime ldt(2022, 01, 31), // winter period
std::time_t t = ldt.timestamp().epochTime();
std::tm then;
then = *std::localtime(&t);
std::cout << "TZ " << then.tm_zone << ", TZD " << ldt.tzd() << ", GMT offset: " << then.tm_gmtoff << std::endl;
if (then.tm_gmtoff != ldt.tzd()) {
	throw Poco::Exception("TZD differs from GMT offset");
}
unsetenv("TZ");

The above example always throws exception for the given time zone.

My suggestion would be to not use timezone external variable from <time.h> in Timezone class but rather calculate utcOffset directly, like:

int Timezone::utcOffset(const Poco::Timestamp& timestamp)
{
	std::time_t time = timestamp.epochTime();
	struct std::tm local;
	if (!localtime_r(&time, &local))
		throw Poco::SystemException("cannot get UTC offset");
	struct std::tm utc;
	gmtime_r(&time, &utc);
	std::time_t utctime = std::mktime(&utc);
	return time - utctime;
}

int Timezone::utcOffset()
{
	return utcOffset(Poco::Timestamp());
}

Pull request (3509) with unit tests created.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions