KTimeZone KTimeZones::remove(const QString &name) { if (!name.isEmpty()) { ZoneMap::Iterator it = d->zones.find(name); if (it != d->zones.end()) { KTimeZone zone = it.value(); d->zones.erase(it); return zone; } } return KTimeZone(); }
KTimeZone KTimeZones::remove(const KTimeZone &zone) { if (zone.isValid()) { for (ZoneMap::Iterator it = d->zones.begin(), end = d->zones.end(); it != end; ++it) { if (it.value() == zone) { d->zones.erase(it); return zone; } } } return KTimeZone(); }
const KstTimezone *KstTimezones::local() { const KstTimezone *local = 0; // First try the simplest solution of checking for well-formed TZ setting. char *envZone = ::getenv("TZ"); if (envZone) { if (envZone[0] == '\0') { return m_UTC; } else if (envZone[0] == ':') { envZone++; } local = zone(envZone); } if (local) return local; // Try to match /etc/localtime against the list of zoneinfo files. QFile f; f.setName("/etc/localtime"); if (f.open(IO_ReadOnly)) { // Compute the MD5 sum of /etc/localtime. KMD5 context(""); context.reset(); context.update(f); QIODevice::Offset referenceSize = f.size(); QString referenceMd5Sum = context.hexDigest(); f.close(); if (!m_zoneinfoDir.isEmpty()) { // Compare it with each zoneinfo file. for (ZoneMap::Iterator it = m_zones->begin(); it != m_zones->end(); ++it) { KstTimezone *zone = it.data(); f.setName(m_zoneinfoDir + '/' + zone->name()); if (f.open(IO_ReadOnly)) { QIODevice::Offset candidateSize = f.size(); QString candidateMd5Sum; if (candidateSize == referenceSize) { // Only do the heavy lifting for file sizes which match. context.reset(); context.update(f); candidateMd5Sum = context.hexDigest(); } f.close(); if (candidateMd5Sum == referenceMd5Sum) { local = zone; break; } } } } } if (local) return local; // BSD support. QString fileZone; f.setName("/etc/timezone"); if (!f.open(IO_ReadOnly)) { // Solaris support using /etc/default/init. f.setName("/etc/default/init"); if (f.open(IO_ReadOnly)) { QTextStream ts(&f); ts.setEncoding(QTextStream::Latin1); // Read the last line starting "TZ=". while (!ts.atEnd()) { fileZone = ts.readLine(); if (fileZone.startsWith("TZ=")) { fileZone = fileZone.mid(3); local = zone(fileZone); } } f.close(); } } else { QTextStream ts(&f); ts.setEncoding(QTextStream::Latin1); // Read the first line. if (!ts.atEnd()) { fileZone = ts.readLine(); local = zone(fileZone); } f.close(); } if (local) return local; // None of the deterministic stuff above has worked: try a heuristic. We // try to find a pair of matching timezone abbreviations...that way, we'll // likely return a value in the user's own country. if (!m_zoneinfoDir.isEmpty()) { tzset(); AbbreviationsMatch matcher(tzname[0], tzname[1]); int bestOffset = INT_MAX; for (ZoneMap::Iterator it = m_zones->begin(); it != m_zones->end(); ++it) { KstTimezone *zone = it.data(); int candidateOffset = QABS(zone->offset(Qt::LocalTime)); if (zone->parse(matcher) && matcher.test() && (candidateOffset < bestOffset)) { bestOffset = candidateOffset; local = zone; } } } if (local) return local; return m_UTC; }