-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Closed
Labels
Description
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.
Reactions are currently unavailable