Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring TZ support #3202

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
3 changes: 3 additions & 0 deletions data/mainRes.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
<qresource prefix="/mainWindow">
<file>icon.bmp</file>
</qresource>
<qresource prefix="/data">
<file>timezone.tab</file>
</qresource>
<qresource prefix="/">
<file>shaders/xyYToRGB.glsl</file>
<file>shaders/preethamAtmosphere.vert</file>
Expand Down
79 changes: 79 additions & 0 deletions data/timezone.tab
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Missing and wrong time zones
#
# This file contains a table of missing and/or wrong time zones.
# Columns are separated by a single tab. Lines beginning with '#' are comments.
# All text uses UTF-8 encoding. The columns of the table are as follows:
#
# 1. DB name
# 2. Name as we display it in the program
#
# This file is automatically retrieved on demand. Do not edit!

# Reported April 25, 2023. (#3200)
America/Yellowknife America/Edmonton
# Seen February 06, 2023.
America/Ciudad_Juarez America/Ojinaga
# Seen November 11, 2022.
America/Thunder_Bay America/Toronto
Europe/Uzhgorod Europe/Kyiv
# Seen on October 27, 2022. TZ Removed?
Europe/Zaporozhye Europe/Kyiv
# Seen on September 26, 2022. Officially renamed.
Europe/Kyiv Europe/Kiev
Europe/Kiev Europe/Kyiv
# Seen in an unrelated bug report, 2022-08-30
Asia/Pyongyang UTC+09:00
# reported in SF forum on 2017-03-27
Europe/Minsk UTC+03:00
Europe/Samara UTC+04:00
America/Cancun UTC-05:00
Asia/Kamchatka UTC+12:00
# Missing on Qt5.7/Win10 as of 2017-03-18.
Europe/Astrakhan UTC+04:00
Europe/Ulyanovsk UTC+04:00
Europe/Kirov UTC+03:00
Asia/Hebron Asia/Jerusalem
# or use UTC+2:00? (political issue...)
Asia/Gaza Asia/Jerusalem
Asia/Kolkata Asia/Calcutta
Asia/Kathmandu Asia/Katmandu
Asia/Tomsk Asia/Novosibirsk
Asia/Barnaul UTC+07:00
Asia/Ho_Chi_Minh Asia/Saigon
Asia/Hovd UTC+07:00
America/Argentina/Buenos_Aires America/Buenos_Aires
America/Argentina/Jujuy America/Jujuy
America/Argentina/Mendoza America/Mendoza
America/Argentina/Catamarca America/Catamarca
America/Argentina/Cordoba America/Cordoba
America/Indiana/Indianapolis America/Indianapolis
America/Kentucky/Louisville America/Louisville
# Small Canadian island.
America/Miquelon UTC-03:00
Africa/Asmara Africa/Asmera
Atlantic/Faroe Atlantic/Faeroe
Pacific/Pohnpei Pacific/Ponape
Pacific/Norfolk UTC+11:00
Pacific/Pitcairn UTC-08:00
# Missing on Qt5.5.1/Ubuntu 16.04.1 LTE as of 2017-03-18:
# NOTE: We must add these following zones for lookup in both ways: When the binary file is being created for publication on Linux, Rangoon/Yangon is being translated.
# UTC+6:30 Yangon missing on Ubuntu/Qt5.5.1.
Asia/Rangoon Asia/Yangon
# This can translate from the binary location file back to the zone name as known on Windows.
Asia/Yangon Asia/Rangoon
# Missing on Qt5.9.5/Ubuntu 18.04.4
America/Godthab UTC-03:00
# Missing on Qt5.12.10/Win7
# no DST; https://www.zeitverschiebung.net/en/timezone/asia--qostanay
Asia/Qostanay UTC+06:00
# no DST; https://www.zeitverschiebung.net/en/timezone/europe--saratov
Europe/Saratov UTC+04:00
# no DST; https://www.zeitverschiebung.net/en/timezone/asia--atyrau
Asia/Atyrau UTC+05:00
# Asia/Nicosia has no DST, but Asia/Famagusta has DST!
Asia/Famagusta Asia/Nicosia
# no DST; https://www.zeitverschiebung.net/en/timezone/america--punta_arenas
America/Punta_Arenas UTC-03:00
# Missing on Qt5.15.2/Win10
America/Nuuk America/Godthab
#:EOF
2 changes: 1 addition & 1 deletion plugins/Exoplanets/src/Exoplanets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,7 @@ void Exoplanets::updateDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
while (bytesTotal > 1024)
{
bytesReceived = static_cast<qint64>(std::floor(static_cast<double>(bytesReceived) / 1024.));
bytesTotal = static_cast<qint64>(std::floor(static_cast<double>(bytesTotal) / 1024.));
bytesTotal = static_cast<qint64>(std::floor(static_cast<double>(bytesTotal) / 1024.));
}
currentValue = static_cast<int>(bytesReceived);
endValue = static_cast<int>(bytesTotal);
Expand Down
121 changes: 52 additions & 69 deletions src/core/StelLocationMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@
#include <QRegularExpression>

TimezoneNameMap StelLocationMgr::locationDBToIANAtranslations;

QString StelLocationMgr::tzfFileName = "data/timezone.tab";
QList<GeoRegion> StelLocationMgr::regions;
QMap<QString, QString> StelLocationMgr::countryCodeToRegionMap;
QMap<QString, QString> StelLocationMgr::countryNameToCodeMap;
bool StelLocationMgr::unknownTZ = false;

#ifdef ENABLE_GPS
#ifdef ENABLE_LIBGPS
Expand Down Expand Up @@ -408,75 +409,11 @@ void NMEALookupHelper::nmeaTimeout()
StelLocationMgr::StelLocationMgr()
: nmeaHelper(Q_NULLPTR), libGpsHelper(Q_NULLPTR)
{
// initialize the static QMap first if necessary.
// The first entry is the DB name, the second is as we display it in the program.
if (locationDBToIANAtranslations.isEmpty())
{
// Reported April 25, 2023. (#3200)
locationDBToIANAtranslations.insert("America/Yellowknife","America/Edmonton");
// Seen February 06, 2023.
locationDBToIANAtranslations.insert("America/Ciudad_Juarez","America/Ojinaga");
// Seen November 11, 2022.
locationDBToIANAtranslations.insert("America/Thunder_Bay","America/Toronto");
locationDBToIANAtranslations.insert("Europe/Uzhgorod", "Europe/Kyiv");
// Seen on October 27, 2022. TZ Removed?
locationDBToIANAtranslations.insert("Europe/Zaporozhye","Europe/Kyiv");
// Seen on September 26, 2022. Officially renamed.
locationDBToIANAtranslations.insert("Europe/Kyiv", "Europe/Kiev");
locationDBToIANAtranslations.insert("Europe/Kiev", "Europe/Kyiv");
// Seen in an unrelated bug report, 2022-08-30
locationDBToIANAtranslations.insert("Asia/Pyongyang", "UTC+09:00");
// reported in SF forum on 2017-03-27
locationDBToIANAtranslations.insert("Europe/Minsk", "UTC+03:00");
locationDBToIANAtranslations.insert("Europe/Samara", "UTC+04:00");
locationDBToIANAtranslations.insert("America/Cancun", "UTC-05:00");
locationDBToIANAtranslations.insert("Asia/Kamchatka", "UTC+12:00");
// Missing on Qt5.7/Win10 as of 2017-03-18.
locationDBToIANAtranslations.insert("Europe/Astrakhan", "UTC+04:00");
locationDBToIANAtranslations.insert("Europe/Ulyanovsk", "UTC+04:00");
locationDBToIANAtranslations.insert("Europe/Kirov", "UTC+03:00");
locationDBToIANAtranslations.insert("Asia/Hebron", "Asia/Jerusalem");
locationDBToIANAtranslations.insert("Asia/Gaza", "Asia/Jerusalem"); // or use UTC+2:00? (political issue...)
locationDBToIANAtranslations.insert("Asia/Kolkata", "Asia/Calcutta");
locationDBToIANAtranslations.insert("Asia/Kathmandu", "Asia/Katmandu");
locationDBToIANAtranslations.insert("Asia/Tomsk", "Asia/Novosibirsk");
locationDBToIANAtranslations.insert("Asia/Barnaul", "UTC+07:00");
locationDBToIANAtranslations.insert("Asia/Ho_Chi_Minh", "Asia/Saigon");
locationDBToIANAtranslations.insert("Asia/Hovd", "UTC+07:00");
locationDBToIANAtranslations.insert("America/Argentina/Buenos_Aires", "America/Buenos_Aires");
locationDBToIANAtranslations.insert("America/Argentina/Jujuy", "America/Jujuy");
locationDBToIANAtranslations.insert("America/Argentina/Mendoza", "America/Mendoza");
locationDBToIANAtranslations.insert("America/Argentina/Catamarca", "America/Catamarca");
locationDBToIANAtranslations.insert("America/Argentina/Cordoba", "America/Cordoba");
locationDBToIANAtranslations.insert("America/Indiana/Indianapolis", "America/Indianapolis");
locationDBToIANAtranslations.insert("America/Kentucky/Louisville", "America/Louisville");
locationDBToIANAtranslations.insert("America/Miquelon", "UTC-03:00"); // Small Canadian island.
locationDBToIANAtranslations.insert("Africa/Asmara", "Africa/Asmera");
locationDBToIANAtranslations.insert("Atlantic/Faroe", "Atlantic/Faeroe");
locationDBToIANAtranslations.insert("Pacific/Pohnpei", "Pacific/Ponape");
locationDBToIANAtranslations.insert("Pacific/Norfolk", "UTC+11:00");
locationDBToIANAtranslations.insert("Pacific/Pitcairn", "UTC-08:00");
// Missing on Qt5.5.1/Ubuntu 16.04.1 LTE as of 2017-03-18:
// NOTE: We must add these following zones for lookup in both ways: When the binary file is being created for publication on Linux, Rangoon/Yangon is being translated.
locationDBToIANAtranslations.insert("Asia/Rangoon", "Asia/Yangon"); // UTC+6:30 Yangon missing on Ubuntu/Qt5.5.1.
locationDBToIANAtranslations.insert("Asia/Yangon", "Asia/Rangoon"); // This can translate from the binary location file back to the zone name as known on Windows.
locationDBToIANAtranslations.insert( "", "UTC");
// Missing on Qt5.9.5/Ubuntu 18.04.4
locationDBToIANAtranslations.insert("America/Godthab", "UTC-03:00");
// Missing on Qt5.12.10/Win7
locationDBToIANAtranslations.insert("Asia/Qostanay", "UTC+06:00"); // no DST; https://www.zeitverschiebung.net/en/timezone/asia--qostanay
locationDBToIANAtranslations.insert("Europe/Saratov", "UTC+04:00"); // no DST; https://www.zeitverschiebung.net/en/timezone/europe--saratov
locationDBToIANAtranslations.insert("Asia/Atyrau", "UTC+05:00"); // no DST; https://www.zeitverschiebung.net/en/timezone/asia--atyrau
locationDBToIANAtranslations.insert("Asia/Famagusta", "Asia/Nicosia"); // Asia/Nicosia has no DST, but Asia/Famagusta has DST!
locationDBToIANAtranslations.insert("America/Punta_Arenas", "UTC-03:00"); // no DST; https://www.zeitverschiebung.net/en/timezone/america--punta_arenas
// Missing on Qt5.15.2/Win10
locationDBToIANAtranslations.insert("America/Nuuk", "America/Godthab");
// N.B. Further missing TZ names will be printed out in the log.txt. Resolve these by adding into this list.
// TODO later: create a text file in user data directory, and auto-update it weekly.
}

QSettings* conf = StelApp::getInstance().getSettings();

// N.B. Further missing TZ names will be printed out in the log.txt. Resolve these by adding into data/timezone.tab file.
loadTimeZoneFixes();

loadCountries();
loadRegions();
// The line below allows to re-generate the location file, you still need to gunzip it manually afterward.
Expand Down Expand Up @@ -591,9 +528,10 @@ LocationMap StelLocationMgr::loadCitiesBin(const QString& fileName)
}
}
}
if (unknownTZlist.length()>0)
if (!unknownTZlist.isEmpty())
{
unknownTZlist.removeDuplicates();
unknownTZ = true;
qDebug() << "StelLocationMgr::loadCitiesBin(): Summary of unknown TimeZones:";
for (const auto& tz : unknownTZlist)
{
Expand Down Expand Up @@ -1246,6 +1184,51 @@ void StelLocationMgr::loadCountries()
countryNameToCodeMap.insert("Taiwan (Provice of China)", "tw");
}

void StelLocationMgr::loadTimeZoneFixes()
{
QString tzFilePath = StelFileMgr::findFile(tzfFileName);
if (tzFilePath.isEmpty())
{
tzFilePath = StelFileMgr::findFile(tzfFileName, StelFileMgr::New);
// Create a default TZF (timezone fixes) file
QFile tzSrc(":/data/timezone.tab");
if (!tzSrc.copy(tzFilePath))
{
qWarning() << "Cannot copy timezone fixes to " + QDir::toNativeSeparators(tzFilePath);
return;
}
QFile dest(tzFilePath);
// fix file permissions
dest.setPermissions(dest.permissions() | QFile::WriteOwner);
}
QFile tzFile(tzFilePath);

if(tzFile.open(QFile::ReadOnly | QFile::Text))
{
locationDBToIANAtranslations.clear();
QString line;
locationDBToIANAtranslations.insert("", "UTC"); // a first fix
int readOk = 1;
static const QRegularExpression dataRx("^([\\w\\/]+)\\t([\\w\\/\\+\\-:]+)\\s*(.*)$");
while(!tzFile.atEnd())
{
line = QString::fromUtf8(tzFile.readLine());
if (line.startsWith("//") || line.startsWith("#") || line.isEmpty())
continue;

QRegularExpressionMatch dataMatch = dataRx.match(line);
if (dataMatch.hasMatch())
{
// The first entry is the DB name, the second is as we display it in the program.
locationDBToIANAtranslations.insert(dataMatch.captured(1).trimmed().toUtf8(), dataMatch.captured(2).trimmed().toUtf8());
readOk++;
}
}
qDebug() << "Loaded" << readOk << "fixes for time zones";
tzFile.close();
}
}

void StelLocationMgr::loadRegions()
{
QFile geoFile(StelFileMgr::findFile("data/regions-geoscheme.tab"));
Expand Down
6 changes: 6 additions & 0 deletions src/core/StelLocationMgr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ class StelLocationMgr : public QObject
//! Pick region name from region code
static QString pickRegionFromCode(int regionCode);

static QString getTZFFileName() { return tzfFileName; }
static bool unknownTimezonesDetected() { return unknownTZ; }

public slots:
//! Return the StelLocation for a given string
//! Can match location name, or coordinates
Expand Down Expand Up @@ -160,6 +163,7 @@ private slots:
private:
void loadRegions();
void loadCountries();
void loadTimeZoneFixes();
void generateBinaryLocationFile(const QString& txtFile, bool isUserLocation, const QString& binFile) const;

//! Load cities from a file
Expand All @@ -182,6 +186,8 @@ private slots:
static QList<GeoRegion> regions;
static QMap<QString, QString> countryCodeToRegionMap;
static QMap<QString, QString> countryNameToCodeMap;
static QString tzfFileName;
static bool unknownTZ;

StelLocation lastResortLocation;

Expand Down
Loading