kdecore: discard leap second adjustments, standard/wall and UTC/local time indicators timezone data

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-06-01 00:49:15 +03:00
parent 25fb60bac6
commit 636f533297
3 changed files with 14 additions and 278 deletions

View file

@ -347,7 +347,6 @@ class KTimeZoneDataPrivate
public: public:
QList<KTimeZone::Phase> phases; QList<KTimeZone::Phase> phases;
QList<KTimeZone::Transition> transitions; QList<KTimeZone::Transition> transitions;
QList<KTimeZone::LeapSeconds> leapChanges;
QList<int> utcOffsets; QList<int> utcOffsets;
QList<QByteArray> abbreviations; QList<QByteArray> abbreviations;
KTimeZone::Phase prePhase; // phase to use before the first transition KTimeZone::Phase prePhase; // phase to use before the first transition
@ -697,11 +696,6 @@ bool KTimeZone::operator==(const KTimeZone &rhs) const
return d->d == rhs.d->d; return d->d == rhs.d->d;
} }
QByteArray KTimeZone::type() const
{
return d->type();
}
bool KTimeZone::isValid() const bool KTimeZone::isValid() const
{ {
return !d->d->name.isEmpty(); return !d->d->name.isEmpty();
@ -795,13 +789,6 @@ QList<QDateTime> KTimeZone::transitionTimes(const Phase &phase, const QDateTime
return d->d->data->transitionTimes(phase, start, end); return d->d->data->transitionTimes(phase, start, end);
} }
QList<KTimeZone::LeapSeconds> KTimeZone::leapSecondChanges() const
{
if (!data(true))
return QList<KTimeZone::LeapSeconds>();
return d->d->data->leapSecondChanges();
}
KTimeZoneSource *KTimeZone::source() const KTimeZoneSource *KTimeZone::source() const
{ {
return d->d->source; return d->d->source;
@ -1034,7 +1021,6 @@ KTimeZoneData *KTimeZoneSource::parse(const KTimeZone &zone) const
quint32 abbrCharCount; // the number of characters of time zone abbreviation strings quint32 abbrCharCount; // the number of characters of time zone abbreviation strings
quint32 ttisgmtcnt; quint32 ttisgmtcnt;
quint8 is;
quint8 T_, Z_, i_, f_; // tzfile identifier prefix quint8 T_, Z_, i_, f_; // tzfile identifier prefix
QString path = zone.name(); QString path = zone.name();
@ -1107,23 +1093,15 @@ KTimeZoneData *KTimeZoneSource::parse(const KTimeZone &zone) const
qint32 gmtoff; // number of seconds to be added to UTC qint32 gmtoff; // number of seconds to be added to UTC
bool isdst; // whether tm_isdst should be set by localtime(3) bool isdst; // whether tm_isdst should be set by localtime(3)
quint8 abbrIndex; // index into the list of time zone abbreviations quint8 abbrIndex; // index into the list of time zone abbreviations
bool isutc; // transition times are in UTC. If UTC, isstd is ignored.
bool isstd; // if true, transition times are in standard time;
// if false, transition times are in wall clock time,
// i.e. standard time or daylight savings time
// whichever is current before the transition
}; };
LocalTimeType *localTimeTypes = new LocalTimeType[nLocalTimeTypes]; LocalTimeType *localTimeTypes = new LocalTimeType[nLocalTimeTypes];
LocalTimeType *ltt = localTimeTypes; LocalTimeType *ltt = localTimeTypes;
for (i = 0; i < nLocalTimeTypes; ++ltt, ++i) for (i = 0; i < nLocalTimeTypes; ++ltt, ++i)
{ {
str >> ltt->gmtoff; str >> ltt->gmtoff;
str >> is; str >> ltt->isdst;
ltt->isdst = (is != 0);
str >> ltt->abbrIndex; str >> ltt->abbrIndex;
// kDebug() << "local type: " << ltt->gmtoff << ", " << is << ", " << ltt->abbrIndex; // kDebug() << "local type: " << ltt->gmtoff << ", " << ltt->isdst << ", " << ltt->abbrIndex;
ltt->isstd = false; // default if no data
ltt->isutc = false; // default if no data
} }
// Read the timezone abbreviations. They are stored as null terminated strings in // Read the timezone abbreviations. They are stored as null terminated strings in
@ -1163,40 +1141,13 @@ KTimeZoneData *KTimeZoneSource::parse(const KTimeZone &zone) const
} }
} }
// Skip the leap second adjustments, standard/wall and UTC/local time indicators.
// Read the leap second adjustments const int skiptotal = (
qint32 t; (nLeapSecondAdjusts * (sizeof(qint32) + sizeof(quint32))) +
quint32 s; (nIsStandard * sizeof(qint8)) +
QList<KTimeZone::LeapSeconds> leapChanges; (nIsUtc * sizeof(qint8))
for (i = 0; i < nLeapSecondAdjusts; ++i) );
{ str.skipRawData(skiptotal);
str >> t >> s;
// kDebug() << "leap entry: " << t << ", " << s;
// Don't use QDateTime::setTime_t() because it takes an unsigned argument
leapChanges += KTimeZone::LeapSeconds(fromTime_t(t), static_cast<int>(s));
}
data->setLeapSecondChanges(leapChanges);
// Read the standard/wall time indicators.
// These are true if the transition times associated with local time types
// are specified as standard time, false if wall clock time.
for (i = 0; i < nIsStandard; ++i)
{
str >> is;
localTimeTypes[i].isstd = (is != 0);
// kDebug() << "standard: " << is;
}
// Read the UTC/local time indicators.
// These are true if the transition times associated with local time types
// are specified as UTC, false if local time.
for (i = 0; i < nIsUtc; ++i)
{
str >> is;
localTimeTypes[i].isutc = (is != 0);
// kDebug() << "UTC: " << is;
}
// Find the starting offset from UTC to use before the first transition time. // Find the starting offset from UTC to use before the first transition time.
// This is first non-daylight savings local time type, or if there is none, // This is first non-daylight savings local time type, or if there is none,
@ -1286,80 +1237,6 @@ QString KTimeZoneSource::location() const
return d->mLocation; return d->mLocation;
} }
/******************************************************************************/
class KTimeZoneLeapSecondsPrivate
{
public:
QDateTime dt; // UTC time when this change occurred
QString comment; // optional comment
int seconds; // number of leap seconds
};
KTimeZone::LeapSeconds::LeapSeconds()
: d(new KTimeZoneLeapSecondsPrivate)
{
}
KTimeZone::LeapSeconds::LeapSeconds(const QDateTime &utc, int leap, const QString &cmt)
: d(new KTimeZoneLeapSecondsPrivate)
{
if (utc.timeSpec() == Qt::UTC) // invalid if start time is not UTC
{
d->dt = utc;
d->comment = cmt;
d->seconds = leap;
}
}
KTimeZone::LeapSeconds::LeapSeconds(const KTimeZone::LeapSeconds &c)
: d(new KTimeZoneLeapSecondsPrivate)
{
d->dt = c.d->dt;
d->comment = c.d->comment;
d->seconds = c.d->seconds;
}
KTimeZone::LeapSeconds::~LeapSeconds()
{
delete d;
}
KTimeZone::LeapSeconds &KTimeZone::LeapSeconds::operator=(const KTimeZone::LeapSeconds &c)
{
d->dt = c.d->dt;
d->comment = c.d->comment;
d->seconds = c.d->seconds;
return *this;
}
bool KTimeZone::LeapSeconds::operator<(const KTimeZone::LeapSeconds& c) const
{
return d->dt < c.d->dt;
}
QDateTime KTimeZone::LeapSeconds::dateTime() const
{
return d->dt;
}
bool KTimeZone::LeapSeconds::isValid() const
{
return d->dt.isValid();
}
int KTimeZone::LeapSeconds::leapSeconds() const
{
return d->seconds;
}
QString KTimeZone::LeapSeconds::comment() const
{
return d->comment;
}
/******************************************************************************/ /******************************************************************************/
@ -1451,7 +1328,6 @@ KTimeZoneData::KTimeZoneData(const KTimeZoneData &c)
{ {
d->phases = c.d->phases; d->phases = c.d->phases;
d->transitions = c.d->transitions; d->transitions = c.d->transitions;
d->leapChanges = c.d->leapChanges;
d->utcOffsets = c.d->utcOffsets; d->utcOffsets = c.d->utcOffsets;
d->abbreviations = c.d->abbreviations; d->abbreviations = c.d->abbreviations;
d->prePhase = c.d->prePhase; d->prePhase = c.d->prePhase;
@ -1466,7 +1342,6 @@ KTimeZoneData &KTimeZoneData::operator=(const KTimeZoneData &c)
{ {
d->phases = c.d->phases; d->phases = c.d->phases;
d->transitions = c.d->transitions; d->transitions = c.d->transitions;
d->leapChanges = c.d->leapChanges;
d->utcOffsets = c.d->utcOffsets; d->utcOffsets = c.d->utcOffsets;
d->abbreviations = c.d->abbreviations; d->abbreviations = c.d->abbreviations;
d->prePhase = c.d->prePhase; d->prePhase = c.d->prePhase;
@ -1667,28 +1542,3 @@ QList<QDateTime> KTimeZoneData::transitionTimes(const KTimeZone::Phase &phase, c
} }
return times; return times;
} }
QList<KTimeZone::LeapSeconds> KTimeZoneData::leapSecondChanges() const
{
return d->leapChanges;
}
void KTimeZoneData::setLeapSecondChanges(const QList<KTimeZone::LeapSeconds> &adjusts)
{
d->leapChanges = adjusts;
}
KTimeZone::LeapSeconds KTimeZoneData::leapSecondChange(const QDateTime &utc) const
{
if (utc.timeSpec() != Qt::UTC)
kError() << "KTimeZoneData::leapSecondChange(): non-UTC time specified";
else
{
for (int i = d->leapChanges.count(); --i >= 0; )
{
if (d->leapChanges[i].dateTime() < utc)
return d->leapChanges[i];
}
}
return KTimeZone::LeapSeconds();
}

View file

@ -46,7 +46,6 @@ class KTimeZonePrivate;
class KTimeZoneSourcePrivate; class KTimeZoneSourcePrivate;
class KTimeZoneDataPrivate; class KTimeZoneDataPrivate;
class KTimeZoneTransitionPrivate; class KTimeZoneTransitionPrivate;
class KTimeZoneLeapSecondsPrivate;
/** @defgroup timezones Time zone classes /** @defgroup timezones Time zone classes
* *
@ -84,9 +83,8 @@ class KTimeZoneLeapSecondsPrivate;
* *
* KTimeZoneData holds the definitions of the different daylight saving time and * KTimeZoneData holds the definitions of the different daylight saving time and
* standard time phases in KTimeZone::Phase objects, and the timed sequence of * standard time phases in KTimeZone::Phase objects, and the timed sequence of
* daylight saving time changes in KTimeZone::Transition objects. Leap seconds * daylight saving time changes in KTimeZone::Transition objects. You can access
* adjustments are held in KTimeZone::LeapSeconds objects. You can access this * this data directly via KTimeZone and KTimeZoneData methods if required.
* data directly via KTimeZone and KTimeZoneData methods if required.
* *
* The mapping of the different classes to external data is as follows: * The mapping of the different classes to external data is as follows:
* *
@ -100,8 +98,7 @@ class KTimeZoneLeapSecondsPrivate;
* adjustments, while still others might contain information on which countries * adjustments, while still others might contain information on which countries
* use the time zone. To allow for this variation, KTimeZoneData is made * use the time zone. To allow for this variation, KTimeZoneData is made
* available for inheritance. When the necessary information is not available, * available for inheritance. When the necessary information is not available,
* the KTimeZone::Phase, KTimeZone::Transition and KTimeZone::LeapSeconds data * the KTimeZone::Phase and KTimeZone::Transition data will be empty.
* will be empty.
* *
* - Each KTimeZoneData class will have a corresponding KTimeZone class, and * - Each KTimeZoneData class will have a corresponding KTimeZone class, and
* related KTimeZoneBackend class, which can interpret its data. * related KTimeZoneBackend class, which can interpret its data.
@ -159,7 +156,7 @@ class KTimeZoneLeapSecondsPrivate;
* // Read the data for 'zoneName' from the new data source. * // Read the data for 'zoneName' from the new data source.
* *
* // Parse what we have read, and write it into 'data'. * // Parse what we have read, and write it into 'data'.
* // Compile the sequence of daylight savings changes and leap * // Compile the sequence of daylight savings changes
* // seconds adjustments (if available) and write into 'data'. * // seconds adjustments (if available) and write into 'data'.
* *
* return data; * return data;
@ -510,62 +507,6 @@ public:
KTimeZoneTransitionPrivate *const d; KTimeZoneTransitionPrivate *const d;
}; };
/*
* Leap seconds adjustment for a time zone.
*
* This class defines a leap seconds adjustment for a time zone by its UTC time of
* occurrence and the cumulative number of leap seconds to be added at that time.
*
* @short Leap seconds adjustment for a time zone
* @see KTimeZone, KTimeZoneData
* @ingroup timezones
* @author David Jarvie <djarvie@kde.org>.
*/
class KDECORE_EXPORT LeapSeconds
{
public:
LeapSeconds();
LeapSeconds(const QDateTime &utcTime, int leapSeconds, const QString &comment = QString());
LeapSeconds(const LeapSeconds &c);
~LeapSeconds();
LeapSeconds &operator=(const LeapSeconds &c);
bool operator<(const LeapSeconds &c) const; // needed by qSort()
/**
* Return whether this instance holds valid data.
*
* @return true if valid, false if invalid
*/
bool isValid() const;
/**
* Return the UTC date/time when this change occurred.
*
* @return date/time
*/
QDateTime dateTime() const;
/**
* Return the cumulative number of leap seconds to be added after this
* change occurs.
*
* @return number of leap seconds
*/
int leapSeconds() const;
/**
* Return the comment (if any) applying to this change.
*
* @return comment
*/
QString comment() const;
private:
KTimeZoneLeapSecondsPrivate *const d;
};
/** /**
* Constructs a null time zone. A null time zone is invalid. * Constructs a null time zone. A null time zone is invalid.
* *
@ -612,15 +553,6 @@ public:
bool operator==(const KTimeZone &rhs) const; bool operator==(const KTimeZone &rhs) const;
bool operator!=(const KTimeZone &rhs) const { return !operator==(rhs); } bool operator!=(const KTimeZone &rhs) const { return !operator==(rhs); }
/**
* Returns the class name of the data represented by this instance.
* If a derived class object has been assigned to this instance, this
* method will return the name of that class.
*
* @return "KTimeZone" or the class name of a derived class
*/
QByteArray type() const;
/** /**
* Checks whether the instance is valid. * Checks whether the instance is valid.
* *
@ -947,17 +879,6 @@ public:
*/ */
QList<QDateTime> transitionTimes(const Phase &phase, const QDateTime &start = QDateTime(), const QDateTime &end = QDateTime()) const; QList<QDateTime> transitionTimes(const Phase &phase, const QDateTime &start = QDateTime(), const QDateTime &end = QDateTime()) const;
/**
* Return all leap second adjustments, in time order.
*
* Note that some time zone data sources (such as system time zones accessed
* via the system libraries) may not provide information on leap second
* adjustments. In such cases, this method will return an empty list.
*
* @return list of adjustments
*/
QList<LeapSeconds> leapSecondChanges() const;
/** /**
* Returns the source reader/parser for the time zone's source database. * Returns the source reader/parser for the time zone's source database.
* *
@ -1273,7 +1194,7 @@ private:
* *
* It contains all the data available from the KTimeZoneSource class, * It contains all the data available from the KTimeZoneSource class,
* including, when available, a complete list of daylight savings time * including, when available, a complete list of daylight savings time
* changes and leap seconds adjustments. * changes.
* *
* This base class can be instantiated, but contains no data. * This base class can be instantiated, but contains no data.
* *
@ -1438,26 +1359,6 @@ public:
*/ */
QList<QDateTime> transitionTimes(const KTimeZone::Phase &phase, const QDateTime &start = QDateTime(), const QDateTime &end = QDateTime()) const; QList<QDateTime> transitionTimes(const KTimeZone::Phase &phase, const QDateTime &start = QDateTime(), const QDateTime &end = QDateTime()) const;
/**
* Return all leap second adjustments, in time order.
*
* Note that some time zone data sources (such as system time zones accessed
* via the system libraries) may not provide information on leap second
* adjustments. In such cases, this method will return an empty list.
*
* @return list of adjustments
*/
QList<KTimeZone::LeapSeconds> leapSecondChanges() const;
/**
* Find the leap second adjustment which is applicable at a given UTC time.
*
* @param utc UTC date/time. An error occurs if @p utc.timeSpec() is not Qt::UTC.
* @return leap second adjustment, or invalid if @p utc is earlier than the
* first leap second adjustment or @p utc is a local time
*/
KTimeZone::LeapSeconds leapSecondChange(const QDateTime &utc) const;
protected: protected:
/** /**
* Initialise the daylight savings time phase list. * Initialise the daylight savings time phase list.
@ -1490,14 +1391,6 @@ protected:
*/ */
void setTransitions(const QList<KTimeZone::Transition> &transitions); void setTransitions(const QList<KTimeZone::Transition> &transitions);
/**
* Initialise the leap seconds adjustment list.
*
* @param adjusts list of adjustments
* @see leapSecondChanges()
*/
void setLeapSecondChanges(const QList<KTimeZone::LeapSeconds> &adjusts);
private: private:
friend KTimeZoneSource; friend KTimeZoneSource;

View file

@ -92,7 +92,6 @@ void KTimeZonesTest::refcount()
KTimeZone tz = timezones.zone("Zone1"); KTimeZone tz = timezones.zone("Zone1");
QVERIFY(tz.isValid()); QVERIFY(tz.isValid());
QCOMPARE(tz.name(), QString("Zone1")); QCOMPARE(tz.name(), QString("Zone1"));
QCOMPARE(tz.type(), QByteArray("KTimeZone"));
} }
/////////////////// ///////////////////
@ -119,7 +118,6 @@ void KTimeZonesTest::local()
KTimeZone local = KSystemTimeZones::local(); KTimeZone local = KSystemTimeZones::local();
QVERIFY(local.isValid()); QVERIFY(local.isValid());
QCOMPARE(local.name(), QString::fromLatin1("Europe/Paris")); QCOMPARE(local.name(), QString::fromLatin1("Europe/Paris"));
QCOMPARE(local.type(), QByteArray("KTimeZone"));
} }
void KTimeZonesTest::zone() void KTimeZonesTest::zone()
@ -438,7 +436,6 @@ void KTimeZonesTest::tzfileDstShifts()
{ {
qDebug() << tz.name(); qDebug() << tz.name();
QVERIFY(tz.isValid()); QVERIFY(tz.isValid());
QCOMPARE(tz.type(), QByteArray("KTimeZone"));
QFile file(QString::fromLatin1(KDESRCDIR) + tz.name().remove(QRegExp("^.+/")) + QLatin1String(".zdump")); QFile file(QString::fromLatin1(KDESRCDIR) + tz.name().remove(QRegExp("^.+/")) + QLatin1String(".zdump"));
QVERIFY(file.open(QIODevice::ReadOnly)); QVERIFY(file.open(QIODevice::ReadOnly));
QTextStream in(&file); QTextStream in(&file);
@ -470,7 +467,6 @@ void KTimeZonesTest::tzfileToZoneTime()
KTimeZoneSource tzsource(KSystemTimeZones::zoneinfoDir()); KTimeZoneSource tzsource(KSystemTimeZones::zoneinfoDir());
KTimeZone london = KTimeZone(&tzsource, "Europe/London"); KTimeZone london = KTimeZone(&tzsource, "Europe/London");
QVERIFY(london.isValid()); QVERIFY(london.isValid());
QCOMPARE(london.type(), QByteArray("KTimeZone"));
QDateTime prepre(QDate(2005,10,29), QTime(23,59,59), Qt::UTC); // before time shift (local time not repeated) QDateTime prepre(QDate(2005,10,29), QTime(23,59,59), Qt::UTC); // before time shift (local time not repeated)
QDateTime pre(QDate(2005,10,30), QTime(0,0,0), Qt::UTC); // before time shift (local time repeated afterwards) QDateTime pre(QDate(2005,10,30), QTime(0,0,0), Qt::UTC); // before time shift (local time repeated afterwards)
QDateTime before(QDate(2005,10,30), QTime(0,59,59), Qt::UTC); // before time shift (local time repeated afterwards) QDateTime before(QDate(2005,10,30), QTime(0,59,59), Qt::UTC); // before time shift (local time repeated afterwards)
@ -520,7 +516,6 @@ void KTimeZonesTest::tzfileOffsetAtUtc()
KTimeZoneSource tzsource(KSystemTimeZones::zoneinfoDir()); KTimeZoneSource tzsource(KSystemTimeZones::zoneinfoDir());
KTimeZone london = KTimeZone(&tzsource, "Europe/London"); KTimeZone london = KTimeZone(&tzsource, "Europe/London");
QVERIFY(london.isValid()); QVERIFY(london.isValid());
QCOMPARE(london.type(), QByteArray("KTimeZone"));
QCOMPARE(london.offsetAtUtc(a3Gmt), 0); QCOMPARE(london.offsetAtUtc(a3Gmt), 0);
QCOMPARE(london.offsetAtUtc(a2Gmt), 0); // uses cache QCOMPARE(london.offsetAtUtc(a2Gmt), 0); // uses cache
QCOMPARE(london.offsetAtUtc(aGmt), 0); // uses cache QCOMPARE(london.offsetAtUtc(aGmt), 0); // uses cache
@ -533,7 +528,6 @@ void KTimeZonesTest::tzfileOffsetAtUtc()
QDateTime recent(QDate(2013,5,10), QTime(13,0,0), Qt::UTC); QDateTime recent(QDate(2013,5,10), QTime(13,0,0), Qt::UTC);
KTimeZone johannesburg = KTimeZone(&tzsource, "Africa/Johannesburg"); KTimeZone johannesburg = KTimeZone(&tzsource, "Africa/Johannesburg");
QVERIFY(johannesburg.isValid()); QVERIFY(johannesburg.isValid());
QCOMPARE(johannesburg.type(), QByteArray("KTimeZone"));
QCOMPARE(johannesburg.offsetAtUtc(recent), 7200); QCOMPARE(johannesburg.offsetAtUtc(recent), 7200);
} }
@ -614,7 +608,6 @@ void KTimeZonesTest::tzfileOffsetAtZoneTime()
KTimeZone johannesburg = KTimeZone(&tzsource, "Africa/Johannesburg"); KTimeZone johannesburg = KTimeZone(&tzsource, "Africa/Johannesburg");
QVERIFY(johannesburg.isValid()); QVERIFY(johannesburg.isValid());
QCOMPARE(johannesburg.type(), QByteArray("KTimeZone"));
QDateTime recent(QDate(2013,5,10), QTime(13,0,0), Qt::LocalTime); QDateTime recent(QDate(2013,5,10), QTime(13,0,0), Qt::LocalTime);
QCOMPARE(johannesburg.offsetAtZoneTime(recent, &offset2), 7200); QCOMPARE(johannesburg.offsetAtZoneTime(recent, &offset2), 7200);
QCOMPARE(offset2, 7200); QCOMPARE(offset2, 7200);