QDateTime uses different time zone offset prior to UNIX epoch?
-
QDateTime initializes with a different time zone offset when passed a QDate before versus after Jan 1 1970. The following line says it all:
QDateTime(QDate(1969, 10, 14)).offsetFromUtc() != QDateTime(QDate(1970, 10, 14)).offsetFromUtc()
It seems to me that the offsets for these two QDateTime objects should be equal. Otherwise, this makes initializing and storing dates difficult.
I assume this is intentional. What is the rationale for this design decision? Is there a workaround?
Cheers,
-Patrick -
A reply from qt interest:
Your test is not reliable. It works for less than half the planet and for just
over half the year.Anyway, there's no workaround. This is done because the timezone databases are
inaccurate before 1970. So we just return each timezone's standard time, not
accounting for DST.This is documented:
The range of valid dates taking DST into account is 1970-01-01 to the
present, and rules are in place for handling DST correctly until 2037-12-31,
but these could change. For dates falling outside that range, QDateTime
makes a \e{best guess} using the rules for year 1970 or 2037, but we can't
guarantee accuracy. This means QDateTime doesn't take into account changes
in a time zone before 1970, even if the system's time zone database provides
that information. -
QDateTime initializes with a different time zone offset when passed a QDate before versus after Jan 1 1970. The following line says it all:
QDateTime(QDate(1969, 10, 14)).offsetFromUtc() != QDateTime(QDate(1970, 10, 14)).offsetFromUtc()
It seems to me that the offsets for these two QDateTime objects should be equal. Otherwise, this makes initializing and storing dates difficult.
I assume this is intentional. What is the rationale for this design decision? Is there a workaround?
Cheers,
-Patrick@patrickkidd said in QDateTime uses different time zone offset prior to UNIX epoch?:
I assume this is intentional. What is the rationale for this design decision? Is there a workaround?
Good question. I suggest you subscribe to the Interest mailing list and ask there. Qt engineers are active on that list, and they're probably in a better position to answer your question.
-
This looks some kind of (Windows?) bug to me:
QDateTime date1(QDate(1969, 10, 14)); QDateTime date2(QDate(1970, 10, 14)); qDebug() << date1.offsetFromUtc() << date1.timeSpec() << date1.timeZone() << date1.isDaylightTime(); qDebug() << date2.offsetFromUtc() << date2.timeSpec() << date2.timeZone() << date2.isDaylightTime();
produces
3600 Qt::TimeSpec(LocalTime) QTimeZone("Europe/Berlin") false 7200 Qt::TimeSpec(LocalTime) QTimeZone("Europe/Berlin") true
On Windows, Linux is correct - there was no DST in Germany in 1970.
/edit: It's mktime which is wrong:
tm local; memset(&local, 0, sizeof(local)); // tm_[wy]day plus any non-standard fields local.tm_mday = 14; local.tm_mon = 9; // starts at 0 local.tm_year = 70; local.tm_isdst = -1;
returns local.tm_isdst = 1 which is wrong.
I still would create a bug report with all the informations provided here. According to https://docs.microsoft.com/de-de/cpp/c-runtime-library/reference/mktime-mktime32-mktime64?view=vs-2019 the 'TZ' env var is maybe involved which could be set by Qt (but I'm not sure). -
This looks some kind of (Windows?) bug to me:
QDateTime date1(QDate(1969, 10, 14)); QDateTime date2(QDate(1970, 10, 14)); qDebug() << date1.offsetFromUtc() << date1.timeSpec() << date1.timeZone() << date1.isDaylightTime(); qDebug() << date2.offsetFromUtc() << date2.timeSpec() << date2.timeZone() << date2.isDaylightTime();
produces
3600 Qt::TimeSpec(LocalTime) QTimeZone("Europe/Berlin") false 7200 Qt::TimeSpec(LocalTime) QTimeZone("Europe/Berlin") true
On Windows, Linux is correct - there was no DST in Germany in 1970.
/edit: It's mktime which is wrong:
tm local; memset(&local, 0, sizeof(local)); // tm_[wy]day plus any non-standard fields local.tm_mday = 14; local.tm_mon = 9; // starts at 0 local.tm_year = 70; local.tm_isdst = -1;
returns local.tm_isdst = 1 which is wrong.
I still would create a bug report with all the informations provided here. According to https://docs.microsoft.com/de-de/cpp/c-runtime-library/reference/mktime-mktime32-mktime64?view=vs-2019 the 'TZ' env var is maybe involved which could be set by Qt (but I'm not sure).@christian-ehrlicher said in QDateTime uses different time zone offset prior to UNIX epoch?:
there was no DST in Germany in 1970
That's really interesting. I wonder if Linux knows there was no DST in Germany after 1950, but there had been between 1939 and 1950 ...?
I wonder if there's some table inside linux that resolves these historical cases ... -
@kshegunov said in QDateTime uses different time zone offset prior to UNIX epoch?:
I wonder if there's some table inside linux that resolves these historical cases ...
Isn't that what the tz database is for?
-
@kshegunov said in QDateTime uses different time zone offset prior to UNIX epoch?:
I wonder if there's some table inside linux that resolves these historical cases ...
Isn't that what the tz database is for?
@christian-ehrlicher said in QDateTime uses different time zone offset prior to UNIX epoch?:
Isn't that what the tz database is for?
Not the faintest clue, hence my question. :)
-
A reply from qt interest:
Your test is not reliable. It works for less than half the planet and for just
over half the year.Anyway, there's no workaround. This is done because the timezone databases are
inaccurate before 1970. So we just return each timezone's standard time, not
accounting for DST.This is documented:
The range of valid dates taking DST into account is 1970-01-01 to the
present, and rules are in place for handling DST correctly until 2037-12-31,
but these could change. For dates falling outside that range, QDateTime
makes a \e{best guess} using the rules for year 1970 or 2037, but we can't
guarantee accuracy. This means QDateTime doesn't take into account changes
in a time zone before 1970, even if the system's time zone database provides
that information.