00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "ksystemtimezone.moc"
00026
00027 #include <config.h>
00028
00029 #ifdef HAVE_SYS_TIME_H
00030 #include <sys/time.h>
00031 #endif
00032 #ifdef HAVE_TIME_H
00033 #include <time.h>
00034 #endif
00035 #include <climits>
00036 #include <cstdlib>
00037
00038 #include <QtCore/QCoreApplication>
00039 #include <QtCore/QFile>
00040 #include <QtCore/QFileInfo>
00041 #include <QtCore/QDir>
00042 #include <QtCore/QRegExp>
00043 #include <QtCore/QStringList>
00044 #include <QtCore/QTextStream>
00045 #include <QtDBus/QDBusConnection>
00046 #include <QtDBus/QDBusInterface>
00047 #include <QtDBus/QDBusReply>
00048
00049 #include <kglobal.h>
00050 #include <klocale.h>
00051 #include <kcodecs.h>
00052 #include <kstringhandler.h>
00053 #include <ktemporaryfile.h>
00054 #include <kdebug.h>
00055 #include <kconfiggroup.h>
00056 #include "ktzfiletimezone.h"
00057
00058
00059 #define KTIMEZONED_DBUS_IFACE "org.kde.KTimeZoned"
00060
00061
00062
00063
00064
00065 int gmtoff(time_t t)
00066 {
00067 #ifdef _POSIX_THREAD_SAFE_FUNCTIONS
00068 tm tmtime;
00069 if (!localtime_r(&t, &tmtime))
00070 return 0;
00071 #ifdef HAVE_TM_GMTOFF
00072 return tmtime.tm_gmtoff;
00073 #else
00074 int lwday = tmtime.tm_wday;
00075 int lt = 3600*tmtime.tm_hour + 60*tmtime.tm_min + tmtime.tm_sec;
00076 if (!gmtime_r(&t, &tmtime))
00077 return 0;
00078 int uwday = tmtime.tm_wday;
00079 int ut = 3600*tmtime.tm_hour + 60*tmtime.tm_min + tmtime.tm_sec;
00080 #endif
00081 #else
00082 tm *tmtime = localtime(&t);
00083 if (!tmtime)
00084 return 0;
00085 #ifdef HAVE_TM_GMTOFF
00086 return tmtime->tm_gmtoff;
00087 #else
00088 int lwday = tmtime->tm_wday;
00089 int lt = 3600*tmtime->tm_hour + 60*tmtime->tm_min + tmtime->tm_sec;
00090 tmtime = gmtime(&t);
00091 int uwday = tmtime->tm_wday;
00092 int ut = 3600*tmtime->tm_hour + 60*tmtime->tm_min + tmtime->tm_sec;
00093 #endif
00094 #endif
00095 #ifndef HAVE_TM_GMTOFF
00096 if (lwday != uwday)
00097 {
00098
00099 if (lwday == uwday + 1 || lwday == 0 && uwday == 6)
00100 lt += 24*3600;
00101 else
00102 lt -= 24*3600;
00103 }
00104 return lt - ut;
00105 #endif
00106 }
00107
00108
00109
00110
00111 class KSystemTimeZonesPrivate : public KTimeZones
00112 {
00113 public:
00114 static KSystemTimeZonesPrivate *instance();
00115 static KTzfileTimeZoneSource *tzfileSource();
00116 static void setLocalZone();
00117 static void cleanup();
00118 static void readConfig(bool init);
00119 #ifndef Q_OS_WIN
00120 static void updateZonetab() { instance()->readZoneTab(true); }
00121 #endif
00122
00123 static KTimeZone m_localZone;
00124 static QString m_localZoneName;
00125 static QString m_zoneinfoDir;
00126 static QString m_zonetab;
00127 static KSystemTimeZoneSource *m_source;
00128
00129 private:
00130 KSystemTimeZonesPrivate() {}
00131 #ifndef Q_OS_WIN
00132 void readZoneTab(bool update);
00133 static float convertCoordinate(const QString &coordinate);
00134 #endif
00135
00136 static KSystemTimeZones *m_parent;
00137 static KSystemTimeZonesPrivate *m_instance;
00138 static KTzfileTimeZoneSource *m_tzfileSource;
00139 };
00140
00141 KTimeZone KSystemTimeZonesPrivate::m_localZone;
00142 QString KSystemTimeZonesPrivate::m_localZoneName;
00143 QString KSystemTimeZonesPrivate::m_zoneinfoDir;
00144 QString KSystemTimeZonesPrivate::m_zonetab;
00145 KSystemTimeZoneSource *KSystemTimeZonesPrivate::m_source = 0;
00146 KTzfileTimeZoneSource *KSystemTimeZonesPrivate::m_tzfileSource = 0;
00147 KSystemTimeZones *KSystemTimeZonesPrivate::m_parent = 0;
00148 KSystemTimeZonesPrivate *KSystemTimeZonesPrivate::m_instance = 0;
00149
00150 KTzfileTimeZoneSource *KSystemTimeZonesPrivate::tzfileSource()
00151 {
00152 if (!m_tzfileSource)
00153 {
00154 instance();
00155 m_tzfileSource = new KTzfileTimeZoneSource(m_zoneinfoDir);
00156 }
00157 return m_tzfileSource;
00158 }
00159
00160
00161 KSystemTimeZones::KSystemTimeZones()
00162 : d(0)
00163 {
00164 QDBusConnection dbus = QDBusConnection::sessionBus();
00165 dbus.connect(QString(), QString(), KTIMEZONED_DBUS_IFACE, "configChanged", this, SLOT(configChanged()));
00166 dbus.connect(QString(), QString(), KTIMEZONED_DBUS_IFACE, "zonetabChanged", this, SLOT(zonetabChanged(QString)));
00167
00168
00169 }
00170
00171 KSystemTimeZones::~KSystemTimeZones()
00172 {
00173 }
00174
00175 KTimeZone KSystemTimeZones::local()
00176 {
00177 KSystemTimeZonesPrivate::instance();
00178 return KSystemTimeZonesPrivate::m_localZone;
00179 }
00180
00181 QString KSystemTimeZones::zoneinfoDir()
00182 {
00183 KSystemTimeZonesPrivate::instance();
00184 return KSystemTimeZonesPrivate::m_zoneinfoDir;
00185 }
00186
00187 KTimeZones *KSystemTimeZones::timeZones()
00188 {
00189 return KSystemTimeZonesPrivate::instance();
00190 }
00191
00192 KTimeZone KSystemTimeZones::readZone(const QString &name)
00193 {
00194 return KTzfileTimeZone(KSystemTimeZonesPrivate::tzfileSource(), name);
00195 }
00196
00197 const KTimeZones::ZoneMap KSystemTimeZones::zones()
00198 {
00199 return KSystemTimeZonesPrivate::instance()->zones();
00200 }
00201
00202 KTimeZone KSystemTimeZones::zone(const QString& name)
00203 {
00204 return KSystemTimeZonesPrivate::instance()->zone(name);
00205 }
00206
00207 void KSystemTimeZones::configChanged()
00208 {
00209 kDebug(161) << "KSystemTimeZones::configChanged()";
00210 KSystemTimeZonesPrivate::readConfig(false);
00211 }
00212
00213 void KSystemTimeZones::zonetabChanged(const QString &zonetab)
00214 {
00215 Q_UNUSED(zonetab)
00216 #ifndef Q_OS_WIN
00217 kDebug(161) << "KSystemTimeZones::zonetabChanged()";
00218
00219
00220 KSystemTimeZonesPrivate::updateZonetab();
00221 #endif
00222 }
00223
00224 void KSystemTimeZones::zoneDefinitionChanged(const QString &zone)
00225 {
00226
00227
00228
00229
00230 Q_UNUSED(zone)
00231 }
00232
00233
00234
00235
00236 KSystemTimeZonesPrivate *KSystemTimeZonesPrivate::instance()
00237 {
00238 if (!m_instance)
00239 {
00240 m_instance = new KSystemTimeZonesPrivate;
00241
00242
00243 m_parent = new KSystemTimeZones;
00244
00245 QDBusInterface *ktimezoned = new QDBusInterface("org.kde.kded", "/modules/ktimezoned", KTIMEZONED_DBUS_IFACE);
00246 QDBusReply<void> reply = ktimezoned->call("initialize", false);
00247 if (!reply.isValid())
00248 kError(161) << "KSystemTimeZones: ktimezoned initialize() D-Bus call failed: " << reply.error().message() << endl;
00249 kDebug(161)<<"instance(): ... initialised";
00250 delete ktimezoned;
00251
00252
00253 readConfig(true);
00254
00255
00256 #ifdef Q_OS_WIN
00257
00258
00259 #else
00260
00261 if (!m_zonetab.isEmpty())
00262 m_instance->readZoneTab(false);
00263 #endif
00264 setLocalZone();
00265 if (!m_localZone.isValid())
00266 m_localZone = KTimeZone::utc();
00267
00268 qAddPostRoutine(KSystemTimeZonesPrivate::cleanup);
00269 }
00270 return m_instance;
00271 }
00272
00273 void KSystemTimeZonesPrivate::readConfig(bool init)
00274 {
00275 KConfig config(QLatin1String("ktimezonedrc"));
00276 if (!init)
00277 config.reparseConfiguration();
00278 KConfigGroup group(&config, "TimeZones");
00279 m_zoneinfoDir = group.readEntry("ZoneinfoDir");
00280 m_zonetab = group.readEntry("Zonetab");
00281 m_localZoneName = group.readEntry("LocalZone");
00282 if (!init)
00283 setLocalZone();
00284 kDebug(161) << "readConfig(): local zone=" << m_localZoneName;
00285 }
00286
00287 void KSystemTimeZonesPrivate::setLocalZone()
00288 {
00289 if (m_localZoneName.startsWith('/'))
00290 {
00291
00292 m_localZone = KTzfileTimeZone(KSystemTimeZonesPrivate::tzfileSource(), m_localZoneName);
00293 if (m_localZone.isValid() && m_instance)
00294 {
00295
00296 KTimeZone oldzone = m_instance->zone(m_localZoneName);
00297 if (!oldzone.isValid() || oldzone.type() != "KTzfileTimeZone")
00298 {
00299 m_instance->remove(oldzone);
00300 m_instance->add(m_localZone);
00301 }
00302 }
00303 }
00304 else
00305 m_localZone = m_instance->zone(m_localZoneName);
00306 }
00307
00308 void KSystemTimeZonesPrivate::cleanup()
00309 {
00310 delete m_parent;
00311 delete m_instance;
00312 delete m_source;
00313 delete m_tzfileSource;
00314 }
00315
00316 #ifndef Q_OS_WIN
00317
00318
00319
00320
00321 void KSystemTimeZonesPrivate::readZoneTab(bool update)
00322 {
00323 kDebug(161) << "readZoneTab(" << m_zonetab<< ")";
00324 QStringList newZones;
00325 QFile f;
00326 f.setFileName(m_zonetab);
00327 if (!f.open(QIODevice::ReadOnly))
00328 return;
00329 QTextStream str(&f);
00330 QRegExp lineSeparator("[ \t]");
00331 QRegExp ordinateSeparator("[+-]");
00332 if (!m_source)
00333 m_source = new KSystemTimeZoneSource;
00334 while (!str.atEnd())
00335 {
00336 QString line = str.readLine();
00337 if (line.isEmpty() || line[0] == '#')
00338 continue;
00339 QStringList tokens = KStringHandler::perlSplit(lineSeparator, line, 4);
00340 int n = tokens.count();
00341 if (n < 3)
00342 {
00343 kError(161) << "readZoneTab(): invalid record: " << line << endl;
00344 continue;
00345 }
00346
00347
00348 int i = tokens[1].indexOf(QRegExp("[+-]"), 1);
00349 if (i < 0)
00350 {
00351 kError(161) << "readZoneTab() " << tokens[2] << ": invalid coordinates: " << tokens[1] << endl;
00352 continue;
00353 }
00354
00355 float latitude = convertCoordinate(tokens[1].left(i));
00356 float longitude = convertCoordinate(tokens[1].mid(i));
00357
00358
00359 if (tokens[0] == "??")
00360 tokens[0] = "";
00361
00362
00363 if (n > 3 && tokens[3] == "-")
00364 tokens[3] = "";
00365 KSystemTimeZone tz(m_source, tokens[2], tokens[0], latitude, longitude, (n > 3 ? tokens[3] : QString()));
00366 if (update)
00367 {
00368
00369 newZones += tz.name();
00370 KTimeZone oldTz = zone(tz.name());
00371 if (oldTz.isValid())
00372 oldTz.updateBase(tz);
00373 else
00374 add(tz);
00375 }
00376 else
00377 add(tz);
00378 }
00379 f.close();
00380
00381 if (update)
00382 {
00383
00384 const ZoneMap oldZones = zones();
00385 for (ZoneMap::const_iterator it = oldZones.begin(); it != oldZones.end(); ++it)
00386 {
00387 if (newZones.indexOf(it.key()) < 0)
00388 remove(it.value());
00389 }
00390 }
00391 }
00392
00396 float KSystemTimeZonesPrivate::convertCoordinate(const QString &coordinate)
00397 {
00398 int value = coordinate.toInt();
00399 int degrees = 0;
00400 int minutes = 0;
00401 int seconds = 0;
00402
00403 if (coordinate.length() > 6)
00404 {
00405 degrees = value / 10000;
00406 value -= degrees * 10000;
00407 minutes = value / 100;
00408 value -= minutes * 100;
00409 seconds = value;
00410 }
00411 else
00412 {
00413 degrees = value / 100;
00414 value -= degrees * 100;
00415 minutes = value;
00416 }
00417 value = degrees * 3600 + minutes * 60 + seconds;
00418 return value / 3600.0;
00419 }
00420 #endif
00421
00422
00423
00424
00425
00426 KSystemTimeZoneBackend::KSystemTimeZoneBackend(KSystemTimeZoneSource *source, const QString &name,
00427 const QString &countryCode, float latitude, float longitude, const QString &comment)
00428 : KTimeZoneBackend(source, name, countryCode, latitude, longitude, comment)
00429 {}
00430
00431 KSystemTimeZoneBackend::~KSystemTimeZoneBackend()
00432 {}
00433
00434 KTimeZoneBackend *KSystemTimeZoneBackend::clone() const
00435 {
00436 return new KSystemTimeZoneBackend(*this);
00437 }
00438
00439 QByteArray KSystemTimeZoneBackend::type() const
00440 {
00441 return "KSystemTimeZone";
00442 }
00443
00444 int KSystemTimeZoneBackend::offsetAtZoneTime(const KTimeZone *caller, const QDateTime &zoneDateTime, int *secondOffset) const
00445 {
00446 if (!caller->isValid() || !zoneDateTime.isValid() || zoneDateTime.timeSpec() != Qt::LocalTime)
00447 return 0;
00448
00449 const QByteArray originalZone = qgetenv("TZ");
00450 QByteArray tz = caller->name().toUtf8();
00451 tz.prepend(":");
00452 bool change = (tz != originalZone);
00453 if (change)
00454 {
00455 ::setenv("TZ", tz, 1);
00456 ::tzset();
00457 }
00458
00459
00460 tm tmtime;
00461 tmtime.tm_sec = zoneDateTime.time().second();
00462 tmtime.tm_min = zoneDateTime.time().minute();
00463 tmtime.tm_hour = zoneDateTime.time().hour();
00464 tmtime.tm_mday = zoneDateTime.date().day();
00465 tmtime.tm_mon = zoneDateTime.date().month() - 1;
00466 tmtime.tm_year = zoneDateTime.date().year() - 1900;
00467 tmtime.tm_isdst = -1;
00468 time_t t = mktime(&tmtime);
00469 int offset1 = (t == (time_t)-1) ? 0 : gmtoff(t);
00470 if (secondOffset)
00471 {
00472 int offset2 = offset1;
00473 if (t != (time_t)-1)
00474 {
00475
00476
00477
00478 int maxShift = 3600;
00479 offset2 = gmtoff(t + maxShift);
00480 if (offset2 < offset1)
00481 {
00482
00483 if (offset1 - offset2 < maxShift)
00484 offset2 = gmtoff(t + (offset1 - offset2));
00485 }
00486 else if ((offset2 = gmtoff(t - maxShift)) > offset1)
00487 {
00488
00489 if (offset2 - offset1 < maxShift)
00490 offset2 = gmtoff(t - (offset2 - offset1));
00491
00492 int o = offset1;
00493 offset1 = offset2;
00494 offset2 = o;
00495 }
00496 else offset2 = offset1;
00497 }
00498 *secondOffset = offset2;
00499 }
00500
00501 if (change)
00502 {
00503
00504 if (originalZone.isEmpty())
00505 ::unsetenv("TZ");
00506 else
00507 ::setenv("TZ", originalZone, 1);
00508 ::tzset();
00509 }
00510 return offset1;
00511 }
00512
00513 int KSystemTimeZoneBackend::offsetAtUtc(const KTimeZone *caller, const QDateTime &utcDateTime) const
00514 {
00515 return offset(caller, KTimeZone::toTime_t(utcDateTime));
00516 }
00517
00518 int KSystemTimeZoneBackend::offset(const KTimeZone *caller, time_t t) const
00519 {
00520 if (!caller->isValid() || t == KTimeZone::InvalidTime_t)
00521 return 0;
00522
00523
00524 const QByteArray originalZone = qgetenv("TZ");
00525 QByteArray tz = caller->name().toUtf8();
00526 tz.prepend(":");
00527 bool change = (tz != originalZone);
00528 if (change)
00529 {
00530 ::setenv("TZ", tz, 1);
00531 ::tzset();
00532 }
00533
00534 int secs = gmtoff(t);
00535
00536 if (change)
00537 {
00538
00539 if (originalZone.isEmpty())
00540 ::unsetenv("TZ");
00541 else
00542 ::setenv("TZ", originalZone, 1);
00543 ::tzset();
00544 }
00545 return secs;
00546 }
00547
00548 bool KSystemTimeZoneBackend::isDstAtUtc(const KTimeZone *caller, const QDateTime &utcDateTime) const
00549 {
00550 return isDst(caller, KTimeZone::toTime_t(utcDateTime));
00551 }
00552
00553 bool KSystemTimeZoneBackend::isDst(const KTimeZone *caller, time_t t) const
00554 {
00555 Q_UNUSED(caller)
00556 if (t != (time_t)-1)
00557 {
00558 #ifdef _POSIX_THREAD_SAFE_FUNCTIONS
00559 tm tmtime;
00560 if (localtime_r(&t, &tmtime))
00561 return tmtime.tm_isdst > 0;
00562 #else
00563 tm *tmtime = localtime(&t);
00564 if (tmtime)
00565 return tmtime->tm_isdst > 0;
00566 #endif
00567 }
00568 return false;
00569 }
00570
00571
00572
00573
00574 KSystemTimeZone::KSystemTimeZone(KSystemTimeZoneSource *source, const QString &name,
00575 const QString &countryCode, float latitude, float longitude, const QString &comment)
00576 : KTimeZone(new KSystemTimeZoneBackend(source, name, countryCode, latitude, longitude, comment))
00577 {
00578 }
00579
00580 KSystemTimeZone::~KSystemTimeZone()
00581 {
00582 }
00583
00584
00585
00586
00587 class KSystemTimeZoneDataPrivate
00588 {
00589 public:
00590 QByteArray TZ;
00591 QList<QByteArray> abbreviations;
00592 };
00593
00594
00595
00596 class KSystemTimeZoneSourcePrivate
00597 {
00598 public:
00599 static void setTZ(const QByteArray &zoneName);
00600 static void restoreTZ();
00601 static char *savedTZ;
00602 static QByteArray originalTZ;
00603 static bool TZIsSaved;
00604 static bool multiParse;
00605 };
00606
00607 char *KSystemTimeZoneSourcePrivate::savedTZ;
00608 QByteArray KSystemTimeZoneSourcePrivate::originalTZ;
00609 bool KSystemTimeZoneSourcePrivate::TZIsSaved = false;
00610 bool KSystemTimeZoneSourcePrivate::multiParse = false;
00611
00612
00613 KSystemTimeZoneSource::KSystemTimeZoneSource()
00614 : d(0)
00615
00616 {
00617 }
00618
00619 KSystemTimeZoneSource::~KSystemTimeZoneSource()
00620 {
00621
00622 }
00623
00624 KTimeZoneData* KSystemTimeZoneSource::parse(const KTimeZone &zone) const
00625 {
00626 QByteArray tz = zone.name().toUtf8();
00627 KSystemTimeZoneSourcePrivate::setTZ(tz);
00628
00629 tzset();
00630 KSystemTimeZoneData* data = new KSystemTimeZoneData;
00631 data->d->TZ = tz;
00632 data->d->abbreviations.append(tzname[0]);
00633 data->d->abbreviations.append(tzname[1]);
00634
00635
00636
00637
00638 KSystemTimeZoneSourcePrivate::restoreTZ();
00639 return data;
00640 }
00641
00642 void KSystemTimeZoneSource::startParseBlock()
00643 {
00644 KSystemTimeZoneSourcePrivate::originalTZ = ::getenv("TZ");
00645 KSystemTimeZoneSourcePrivate::multiParse = true;
00646 }
00647
00648 void KSystemTimeZoneSource::endParseBlock()
00649 {
00650 if (KSystemTimeZoneSourcePrivate::multiParse)
00651 {
00652
00653 if (KSystemTimeZoneSourcePrivate::originalTZ.isEmpty())
00654 ::unsetenv("TZ");
00655 else
00656 ::setenv("TZ", KSystemTimeZoneSourcePrivate::originalTZ, 1);
00657 ::tzset();
00658 KSystemTimeZoneSourcePrivate::multiParse = false;
00659 }
00660 }
00661
00662
00663
00664 void KSystemTimeZoneSourcePrivate::setTZ(const QByteArray &zoneName)
00665 {
00666 QByteArray tz = zoneName;
00667 tz.prepend(":");
00668 bool setTZ = multiParse;
00669 if (!setTZ)
00670 {
00671 savedTZ = ::getenv("TZ");
00672 TZIsSaved = true;
00673 setTZ = (tz != savedTZ);
00674 }
00675 if (setTZ)
00676 {
00677 ::setenv("TZ", tz, 1);
00678 ::tzset();
00679 }
00680 }
00681
00682
00683 void KSystemTimeZoneSourcePrivate::restoreTZ()
00684 {
00685 if (TZIsSaved)
00686 {
00687 if (!savedTZ)
00688 ::unsetenv("TZ");
00689 else
00690 ::setenv("TZ", savedTZ, 1);
00691 ::tzset();
00692 TZIsSaved = false;
00693 }
00694 }
00695
00696
00697
00698
00699 KSystemTimeZoneData::KSystemTimeZoneData()
00700 : d(new KSystemTimeZoneDataPrivate)
00701 { }
00702
00703 KSystemTimeZoneData::KSystemTimeZoneData(const KSystemTimeZoneData &rhs)
00704 : KTimeZoneData(),
00705 d(new KSystemTimeZoneDataPrivate)
00706 {
00707 operator=(rhs);
00708 }
00709
00710 KSystemTimeZoneData::~KSystemTimeZoneData()
00711 {
00712 delete d;
00713 }
00714
00715 KSystemTimeZoneData &KSystemTimeZoneData::operator=(const KSystemTimeZoneData &rhs)
00716 {
00717 d->TZ = rhs.d->TZ;
00718 d->abbreviations = rhs.d->abbreviations;
00719 return *this;
00720 }
00721
00722 KTimeZoneData *KSystemTimeZoneData::clone() const
00723 {
00724 return new KSystemTimeZoneData(*this);
00725 }
00726
00727 QList<QByteArray> KSystemTimeZoneData::abbreviations() const
00728 {
00729 return d->abbreviations;
00730 }
00731
00732 QByteArray KSystemTimeZoneData::abbreviation(const QDateTime &utcDateTime) const
00733 {
00734 QByteArray abbr;
00735 if (utcDateTime.timeSpec() != Qt::UTC)
00736 return abbr;
00737 time_t t = utcDateTime.toTime_t();
00738 if (t != KTimeZone::InvalidTime_t)
00739 {
00740 KSystemTimeZoneSourcePrivate::setTZ(d->TZ);
00741
00742
00743
00744
00745
00746 #ifdef _POSIX_THREAD_SAFE_FUNCTIONS
00747 tm tmtime;
00748 if (localtime_r(&t, &tmtime))
00749 #ifdef HAVE_STRUCT_TM_TM_ZONE
00750 abbr = tmtime.tm_zone;
00751 #else
00752 abbr = tzname[(tmtime.tm_isdst > 0) ? 1 : 0];
00753 #endif
00754 #else
00755 tm *tmtime = localtime(&t);
00756 if (tmtime)
00757 #ifdef HAVE_STRUCT_TM_TM_ZONE
00758 abbr = tmtime->tm_zone;
00759 #else
00760 abbr = tzname[(tmtime->tm_isdst > 0) ? 1 : 0];
00761 #endif
00762 #endif
00763 KSystemTimeZoneSourcePrivate::restoreTZ();
00764 }
00765 return abbr;
00766 }
00767
00768 QList<int> KSystemTimeZoneData::utcOffsets() const
00769 {
00770 return QList<int>();
00771 }