25 #ifdef HAVE_SYS_TIME_H
32 #include <QtCore/QFile>
33 #include <QtCore/QDataStream>
34 #include <QtCore/QVector>
43 static const QDate epochDate(1970,1,1);
44 static const QTime epochTime(0,0,0);
45 int days = seconds / 86400;
46 seconds -= days * 86400;
52 return QDateTime(epochDate.addDays(days), epochTime.addSecs(seconds), Qt::UTC);
58 const QString &countryCode,
float latitude,
float longitude,
const QString &comment)
72 return "KTzfileTimeZone";
85 const QString &countryCode,
float latitude,
float longitude,
96 class KTzfileTimeZoneDataPrivate
136 class KTzfileTimeZoneSourcePrivate
139 KTzfileTimeZoneSourcePrivate(
const QString &loc)
141 ~KTzfileTimeZoneSourcePrivate() {}
148 : d(new KTzfileTimeZoneSourcePrivate(location))
150 if (location.length() > 1 && location.endsWith(QLatin1Char(
'/')))
169 quint8 T_, Z_, i_, f_;
172 if (!path.startsWith(QLatin1Char(
'/')))
174 if (d->location == QLatin1String(
"/"))
175 path.prepend(d->location);
177 path = d->location + QLatin1Char(
'/') + path;
180 if (!f.open(QIODevice::ReadOnly))
182 kError() <<
"Cannot open " << f.fileName() << endl;
188 str >> T_ >> Z_ >> i_ >> f_;
189 if (T_ !=
'T' || Z_ !=
'Z' || i_ !=
'i' || f_ !=
'f')
191 kError() <<
"Not a TZFILE: " << f.fileName() << endl;
196 for (i = 0; i < 4; ++i)
209 >> nLeapSecondAdjusts
217 struct TransitionTime
220 quint8 localTimeIndex;
223 TransitionTime *transitionTimes =
new TransitionTime[nTransitionTimes];
224 for (i = 0; i < nTransitionTimes; ++i)
226 str >> transitionTimes[i].time;
228 for (i = 0; i < nTransitionTimes; ++i)
230 str >> transitionTimes[i].localTimeIndex;
246 LocalTimeType *localTimeTypes =
new LocalTimeType[nLocalTimeTypes];
247 LocalTimeType *ltt = localTimeTypes;
248 for (i = 0; i < nLocalTimeTypes; ++ltt, ++i)
252 ltt->isdst = (is != 0);
253 str >> ltt->abbrIndex;
262 if (abbrCharCount > 64)
264 kError() <<
"excessive length for timezone abbreviations: " << abbrCharCount << endl;
266 delete[] transitionTimes;
267 delete[] localTimeTypes;
270 QByteArray array(abbrCharCount, 0);
271 str.readRawData(array.data(), array.size());
272 const char *abbrs = array.constData();
273 if (abbrs[abbrCharCount - 1] != 0)
276 kError() <<
"timezone abbreviations not null terminated: " << abbrs[abbrCharCount - 1] << endl;
278 delete[] transitionTimes;
279 delete[] localTimeTypes;
283 QList<QByteArray> abbreviations;
284 for (i = 0; i < abbrCharCount; ++n, i += strlen(abbrs + i) + 1)
286 abbreviations += QByteArray(abbrs + i);
288 ltt = localTimeTypes;
289 for (
unsigned j = 0; j < nLocalTimeTypes; ++ltt, ++j)
291 if (ltt->abbrIndex == i)
300 QList<KTimeZone::LeapSeconds> leapChanges;
301 for (i = 0; i < nLeapSecondAdjusts; ++i)
313 for (i = 0; i < nIsStandard; ++i)
316 localTimeTypes[i].isstd = (is != 0);
323 for (i = 0; i < nIsUtc; ++i)
326 localTimeTypes[i].isutc = (is != 0);
334 LocalTimeType* firstLtt = 0;
335 ltt = localTimeTypes;
336 for (i = 0; i < nLocalTimeTypes; ++ltt, ++i)
349 QList<KTimeZone::Phase> phases;
350 QList<QByteArray> phaseAbbrevs;
351 QVector<int> lttLookup(nLocalTimeTypes);
352 ltt = localTimeTypes;
353 for (i = 0; i < nLocalTimeTypes; ++ltt, ++i)
355 if (ltt->abbrIndex >= abbreviations.count())
357 kError() <<
"KTzfileTimeZoneSource::parse(): abbreviation index out of range" << endl;
361 abbrev = abbreviations[ltt->abbrIndex];
364 for (
int j = 0, jend = phases.count(); j < jend; ++j, ++phindex)
366 if (ltt->gmtoff == phases[j].utcOffset()
367 && (
bool)ltt->isdst == phases[j].isDst()
368 && abbrev == phaseAbbrevs[j])
371 lttLookup[i] = phindex;
372 if (phindex == phases.count())
375 phaseAbbrevs += abbrev;
379 (firstLtt->abbrIndex < abbreviations.count() ? abbreviations[firstLtt->abbrIndex] :
""),
385 TransitionTime *tt = transitionTimes;
386 for (i = 0; i < nTransitionTimes; ++tt, ++i)
388 if (tt->localTimeIndex >= nLocalTimeTypes)
390 kError() <<
"KTzfileTimeZoneSource::parse(): transition ignored: local time type out of range: " <<(int)tt->localTimeIndex<<
" > "<<nLocalTimeTypes << endl;
395 ltt = &localTimeTypes[tt->localTimeIndex];
403 delete[] localTimeTypes;
404 delete[] transitionTimes;