[PATCH] Fix Qt date interfaces for times before 1970

Linus Torvalds torvalds at linux-foundation.org
Thu Apr 28 16:31:37 PDT 2016


This seems to work around the crazy QDateTime::fromTime_t() problem in Qt.

It is *very* lightly tested. In fact, the only test is that "test0.xml" 
change that is part of this patch.

Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
---

I hope that just setting "Qt::UTC" means that all the date string 
translation will be done in UTC. That would almost make up for the fact 
that the fromTime_t() member function is pure shit.

 core/qthelper.cpp                       |  2 +-
 core/subsurface-qt/DiveObjectHelper.cpp | 17 ++++++++---------
 desktop-widgets/maintab.cpp             |  6 +++---
 dives/test0.xml                         |  2 +-
 4 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/core/qthelper.cpp b/core/qthelper.cpp
index a261cca388bf..86c8816bcb93 100644
--- a/core/qthelper.cpp
+++ b/core/qthelper.cpp
@@ -950,7 +950,7 @@ QString get_trip_date_string(timestamp_t when, int nr, bool getday)
 {
 	struct tm tm;
 	utc_mkdate(when, &tm);
-	QDateTime localTime = QDateTime::fromTime_t(when);
+	QDateTime localTime = QDateTime::fromMSecsSinceEpoch(1000*when,Qt::UTC);
 	localTime.setTimeSpec(Qt::UTC);
 	QString ret ;
 
diff --git a/core/subsurface-qt/DiveObjectHelper.cpp b/core/subsurface-qt/DiveObjectHelper.cpp
index 9a3f2386d075..ea890a13513c 100644
--- a/core/subsurface-qt/DiveObjectHelper.cpp
+++ b/core/subsurface-qt/DiveObjectHelper.cpp
@@ -73,7 +73,7 @@ int DiveObjectHelper::id() const
 
 QString DiveObjectHelper::date() const
 {
-	QDateTime localTime = QDateTime::fromTime_t(m_dive->when - gettimezoneoffset(m_dive->when));
+	QDateTime localTime = QDateTime::fromMSecsSinceEpoch(1000*m_dive->when, Qt::UTC);
 	localTime.setTimeSpec(Qt::UTC);
 	return localTime.date().toString(prefs.date_format);
 }
@@ -85,7 +85,7 @@ timestamp_t DiveObjectHelper::timestamp() const
 
 QString DiveObjectHelper::time() const
 {
-	QDateTime localTime = QDateTime::fromTime_t(m_dive->when - gettimezoneoffset(m_dive->when));
+	QDateTime localTime = QDateTime::fromMSecsSinceEpoch(1000*m_dive->when, Qt::UTC);
 	localTime.setTimeSpec(Qt::UTC);
 	return localTime.time().toString(prefs.time_format);
 }
@@ -288,13 +288,12 @@ QString DiveObjectHelper::tripMeta() const
 		QString title(dt->location);
 		if (title.isEmpty()) {
 			// so use the date range
-			timestamp_t firstTime = dt->when - gettimezoneoffset(dt->when);
-			QString firstMonth = QDateTime::fromTime_t(firstTime).toString("MMM");
-			QString firstYear = QDateTime::fromTime_t(firstTime).toString("yyyy");
-			struct dive *lastDive = dt->dives;
-			timestamp_t lastTime = lastDive->when - gettimezoneoffset(lastDive->when);
-			QString lastMonth = QDateTime::fromTime_t(lastTime).toString("MMM");
-			QString lastYear = QDateTime::fromTime_t(lastTime).toString("yyyy");
+			QDateTime firstTime = QDateTime::fromMSecsSinceEpoch(1000*dt->when, Qt::UTC);
+			QString firstMonth = firstTime.toString("MMM");
+			QString firstYear = firstTime.toString("yyyy");
+			QDateTime lastTime = QDateTime::fromMSecsSinceEpoch(1000*dt->dives->when, Qt::UTC);
+			QString lastMonth = lastTime.toString("MMM");
+			QString lastYear = lastTime.toString("yyyy");
 			if (lastMonth == firstMonth && lastYear == firstYear)
 				title = firstMonth + " " + firstYear;
 			else if (lastMonth != firstMonth && lastYear == firstYear)
diff --git a/desktop-widgets/maintab.cpp b/desktop-widgets/maintab.cpp
index a3cc151ef271..f6e5b7dc60bc 100644
--- a/desktop-widgets/maintab.cpp
+++ b/desktop-widgets/maintab.cpp
@@ -493,7 +493,7 @@ void MainTab::updateDiveInfo(bool clear)
 
 		// Subsurface always uses "local time" as in "whatever was the local time at the location"
 		// so all time stamps have no time zone information and are in UTC
-		QDateTime localTime = QDateTime::fromTime_t(displayed_dive.when - gettimezoneoffset(displayed_dive.when));
+		QDateTime localTime = QDateTime::fromMSecsSinceEpoch(1000*displayed_dive.when, Qt::UTC);
 		localTime.setTimeSpec(Qt::UTC);
 		ui.dateEdit->setDate(localTime.date());
 		ui.timeEdit->setTime(localTime.time());
@@ -1284,7 +1284,7 @@ void MainTab::on_dateEdit_dateChanged(const QDate &date)
 	if (editMode == IGNORE || acceptingEdit == true)
 		return;
 	markChangedWidget(ui.dateEdit);
-	QDateTime dateTime = QDateTime::fromTime_t(displayed_dive.when - gettimezoneoffset(displayed_dive.when));
+	QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(1000*displayed_dive.when, Qt::UTC);
 	dateTime.setTimeSpec(Qt::UTC);
 	dateTime.setDate(date);
 	DivePlannerPointsModel::instance()->getDiveplan().when = displayed_dive.when = dateTime.toTime_t();
@@ -1296,7 +1296,7 @@ void MainTab::on_timeEdit_timeChanged(const QTime &time)
 	if (editMode == IGNORE || acceptingEdit == true)
 		return;
 	markChangedWidget(ui.timeEdit);
-	QDateTime dateTime = QDateTime::fromTime_t(displayed_dive.when - gettimezoneoffset(displayed_dive.when));
+	QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(1000*displayed_dive.when, Qt::UTC);
 	dateTime.setTimeSpec(Qt::UTC);
 	dateTime.setTime(time);
 	DivePlannerPointsModel::instance()->getDiveplan().when = displayed_dive.when = dateTime.toTime_t();
diff --git a/dives/test0.xml b/dives/test0.xml
index 6ade06519692..75ad23e7d1f2 100644
--- a/dives/test0.xml
+++ b/dives/test0.xml
@@ -1,6 +1,6 @@
 <dives>
   <program name='subsurface' version='1'></program>
-  <dive number='0' date='2011-01-01' time='07:00:00' duration='30:00 min'>
+  <dive number='0' date='1968-01-01' time='07:00:00' duration='30:00 min'>
     <depth max='30.00 m' mean='15.00 m' />
   </dive>
 </dives>


More information about the subsurface mailing list