22 #include <ktimezones.h>
25 #include <tdeprocess.h>
26 #include <kstringhandler.h>
27 #include <tdetempfile.h>
29 #include <tqdatetime.h>
32 #include <tqstringlist.h>
33 #include <tqtextstream.h>
41 #define UTC_ZONE "UTC"
51 class AbbreviationsMatch :
55 AbbreviationsMatch(
const TQString &stdZone,
const TQString &dstZone =
"")
64 m_foundDst = m_dstZone.isEmpty();
69 return (m_foundStd && m_foundDst);
80 if (m_stdZone == value)
84 if (m_dstZone == value)
116 OffsetFind(
unsigned dateTime)
118 m_dateTime = dateTime;
123 m_transitionTimeIndex = 0;
124 m_localTimeIndex = -1;
141 TQString abbreviation()
148 int m_transitionTimeIndex;
149 int m_localTimeIndex;
157 if (transitionTime <= m_dateTime)
160 m_transitionTimeIndex = index;
166 if (index == m_transitionTimeIndex)
169 m_localTimeIndex = localTimeIndex;
173 virtual void gotLocalTime(
int index,
int gmtOff,
bool isDst,
unsigned abbrInd)
175 if (index == m_localTimeIndex)
180 m_abbrIndex = abbrInd;
186 if (index == m_abbrIndex)
207 const TQString &countryCode,
float latitude,
float longitude,
208 const TQString &comment) :
211 m_countryCode(countryCode),
212 m_latitude(latitude),
213 m_longitude(longitude),
218 if (m_latitude * m_latitude > 90 * 90)
220 if (m_longitude * m_longitude > 180 * 180)
224 KTimezone::~KTimezone()
237 char *originalZone = ::getenv(
"TZ");
240 ::setenv(
"TZ", m_name.utf8(), 1);
242 unsigned utc = dateTime.toTime_t();
245 ::setenv(
"TZ", newZone->
name().utf8(), 1);
247 TQDateTime remoteTime;
248 remoteTime.setTime_t(utc, TQt::LocalTime);
257 ::setenv(
"TZ", originalZone, 1);
265 return m_countryCode;
285 char *originalZone = ::getenv(
"TZ");
288 TQDateTime basisTime = TQDateTime::currentDateTime(basisSpec);
291 ::setenv(
"TZ", m_name.utf8(), 1);
293 TQDateTime remoteTime = TQDateTime::currentDateTime(TQt::LocalTime);
294 int offset = remoteTime.secsTo(basisTime);
303 ::setenv(
"TZ", originalZone, 1);
311 OffsetFind finder(dateTime.toTime_t());
315 result = finder.offset();
323 bool result = m_db->
parse(m_name, dataReceiver);
328 KTimezones::KTimezones() :
335 m_UTC =
new KTimezone(
new DummySource(), UTC_ZONE);
339 KTimezones::~KTimezones()
347 for (ZoneMap::ConstIterator it = m_zones->begin(); it != m_zones->end(); ++it)
365 m_zones =
new ZoneMap();
374 m_zoneinfoDir =
"/usr/share/zoneinfo";
375 f.setName(m_zoneinfoDir +
"/zone.tab");
376 if (!f.open(IO_ReadOnly))
378 kdDebug() <<
"Can't open " << f.name() <<
endl;
379 m_zoneinfoDir =
"/usr/lib/zoneinfo";
380 f.setName(m_zoneinfoDir +
"/zone.tab");
381 if (!f.open(IO_ReadOnly))
383 kdDebug() <<
"Can't open " << f.name() <<
endl;
384 m_zoneinfoDir = ::getenv(
"TZDIR");
385 f.setName(m_zoneinfoDir +
"/zone.tab");
386 if (m_zoneinfoDir.isEmpty() || !f.open(IO_ReadOnly))
388 kdDebug() <<
"Can't open " << f.name() <<
endl;
396 m_zoneinfoDir =
"/usr/share/lib/zoneinfo";
399 reader <<
"/bin/grep" <<
"-h" <<
"^Zone" << m_zoneinfoDir <<
"/src/*" << temp.
name() <<
"|" <<
400 "/bin/awk" <<
"'{print \"??\\t+9999+99999\\t\" $2}'";
404 f.setName(temp.
name());
405 if (!temp.
status() || !f.open(IO_ReadOnly))
407 kdDebug() <<
"Can't open " << f.name() <<
endl;
415 TQTextStream str(&f);
416 TQRegExp lineSeparator(
"[ \t]");
417 TQRegExp ordinateSeparator(
"[+-]");
421 TQString line = str.readLine();
422 if (line.isEmpty() ||
'#' == line[0])
425 if (tokens.count() < 3)
427 kdError() <<
"invalid record: " << line <<
endl;
433 if (ordinates.count() < 2)
435 kdError() <<
"invalid coordinates: " << tokens[1] <<
endl;
439 float latitude = convertCoordinate(ordinates[1]);
440 float longitude = convertCoordinate(ordinates[2]);
443 if (tokens[0] ==
"??")
445 KTimezone *timezone =
new KTimezone(db, tokens[2], tokens[0], latitude, longitude, tokens[3]);
455 float KTimezones::convertCoordinate(
const TQString &coordinate)
457 int value = coordinate.toInt();
462 if (coordinate.length() > 11)
464 degrees = value / 10000;
465 value -= degrees * 10000;
466 minutes = value / 100;
467 value -= minutes * 100;
472 degrees = value / 100;
473 value -= degrees * 100;
476 value = degrees * 3600 + minutes * 60 + seconds;
477 return value / 3600.0;
485 char *envZone = ::getenv(
"TZ");
488 if (envZone[0] ==
'\0')
493 if (envZone[0] ==
':')
504 f.setName(
"/etc/localtime");
505 if (f.open(IO_ReadOnly))
511 TQIODevice::Offset referenceSize = f.size();
512 TQString referenceMd5Sum = context.
hexDigest();
514 if (!m_zoneinfoDir.isEmpty())
517 for (ZoneMap::Iterator it = m_zones->begin(); it != m_zones->end(); ++it)
520 f.setName(m_zoneinfoDir +
'/' +
zone->
name());
521 if (f.open(IO_ReadOnly))
523 TQIODevice::Offset candidateSize = f.size();
524 TQString candidateMd5Sum;
525 if (candidateSize == referenceSize)
533 if (candidateMd5Sum == referenceMd5Sum)
548 f.setName(
"/etc/timezone");
549 if (!f.open(IO_ReadOnly))
551 kdDebug() <<
"Can't open " << f.name() <<
endl;
554 f.setName(
"/etc/default/init");
555 if (!f.open(IO_ReadOnly))
557 kdDebug() <<
"Can't open " << f.name() <<
endl;
562 ts.setEncoding(TQTextStream::Latin1);
567 fileZone = ts.readLine();
568 if (fileZone.startsWith(
"TZ="))
570 fileZone = fileZone.mid(3);
582 ts.setEncoding(TQTextStream::Latin1);
587 fileZone = ts.readLine();
600 if (!m_zoneinfoDir.isEmpty())
603 AbbreviationsMatch matcher(tzname[0], tzname[1]);
604 int bestOffset = INT_MAX;
605 for (ZoneMap::Iterator it = m_zones->begin(); it != m_zones->end(); ++it)
608 int candidateOffset = TQABS(
zone->
offset(TQt::LocalTime));
609 if (
zone->
parse(matcher) && matcher.test() && (candidateOffset < bestOffset))
612 bestOffset = candidateOffset;
626 ZoneMap::ConstIterator it = m_zones->find(name);
627 if (it != m_zones->end())
634 KTimezoneDetails::KTimezoneDetails()
638 KTimezoneDetails::~KTimezoneDetails()
646 unsigned,
unsigned,
unsigned,
647 unsigned,
unsigned,
unsigned)
674 KTimezoneSource::KTimezoneSource(
const TQString &db) :
679 KTimezoneSource::~KTimezoneSource()
690 TQFile f(m_db +
'/' + zone);
691 if (!f.open(IO_ReadOnly))
693 kdError() <<
"Cannot open " << f.name() <<
endl;
698 TQ_UINT8 T, z, i_, f_;
701 TQ_UINT32 ttisgmtcnt;
702 TQ_UINT32 ttisstdcnt;
708 TQ_UINT32 transitionTime;
709 TQ_UINT8 localTimeIndex;
717 TQ_UINT32 leapSeconds;
721 TQDataStream str(&f);
722 str >> T >> z >> i_ >> f_;
725 for (i = 0; i < 4; i++)
726 str >> tzh.ttisgmtcnt;
727 str >> tzh.ttisgmtcnt >> tzh.ttisstdcnt >> tzh.leapcnt >> tzh.timecnt >> tzh.typecnt >> tzh.charcnt;
730 dataReceiver.
gotHeader(tzh.ttisgmtcnt, tzh.ttisstdcnt, tzh.leapcnt, tzh.timecnt, tzh.typecnt, tzh.charcnt);
731 for (i = 0; i < tzh.timecnt; i++)
733 str >> transitionTime;
736 for (i = 0; i < tzh.timecnt; i++)
739 str >> localTimeIndex;
742 for (i = 0; i < tzh.typecnt; i++)
744 str >> tt.gmtoff >> tt.isdst >> tt.abbrind;
746 dataReceiver.
gotLocalTime(i, tt.gmtoff, (tt.isdst != 0), tt.abbrind);
750 if (tzh.charcnt > 64)
752 kdError() <<
"excessive length for timezone abbreviations: " << tzh.charcnt <<
endl;
755 TQByteArray array(tzh.charcnt);
756 str.readRawBytes(array.data(), array.size());
757 char *abbrs = array.data();
758 if (abbrs[tzh.charcnt - 1] != 0)
761 kdError() <<
"timezone abbreviations not terminated: " << abbrs[tzh.charcnt - 1] <<
endl;
765 while (abbr < abbrs + tzh.charcnt)
769 abbr += strlen(abbr) + 1;
771 for (i = 0; i < tzh.leapcnt; i++)
773 str >> leapTime >> leapSeconds;
777 for (i = 0; i < tzh.ttisstdcnt; i++)
783 for (i = 0; i < tzh.ttisgmtcnt; i++)
787 dataReceiver.
gotIsUTC(i, (isUTC != 0));
An adapted C++ implementation of RSA Data Securities MD5 algorithm.
void update(const char *in, int len=-1)
Updates the message to be digested.
TQCString hexDigest()
Returns the value of the calculated message digest in a hexadecimal representation.
void reset()
Calling this function will reset the calculated message digest.
A class derived from TDEProcess to start child processes through a shell.
virtual bool start(RunMode runmode=NotifyOnExit, Communication comm=NoCommunication)
Starts the process.
static TQStringList perlSplit(const TQString &sep, const TQString &s, uint max=0)
Split a TQString into a TQStringList in a similar fashion to the static TQStringList function in Qt,...
The KTempFile class creates and opens a unique file for temporary use.
int status() const
Returns the status of the file based on errno.
bool close()
Closes the file.
TQString name() const
Returns the full path and name of the file.
The KTimezoneDetails class contains extended functions related to a timezone.
virtual void gotHeader(unsigned ttIsGmtCnt, unsigned ttIsStdCnt, unsigned leapCnt, unsigned timeCnt, unsigned typeCnt, unsigned charCnt)
Called when the header is seen.
virtual void parseEnded()
Always called after all other callbacks.
virtual void gotLeapAdjustment(int index, unsigned leapTime, unsigned leapSeconds)
Called when a leap second adjustment is seen.
virtual void gotLocalTime(int index, int gmtOff, bool isDst, unsigned abbrIndex)
Called when a local time is seen.
virtual void gotIsUTC(int index, bool isUTC)
Called when a UTC/local time indicator is seen.
virtual void gotLocalTimeIndex(int index, unsigned localTimeIndex)
Called when a local time index is seen.
virtual void gotIsStandard(int index, bool isStandard)
Called when a standard/wall time indicator is seen.
virtual void parseStarted()
Always called before any other callback.
virtual void gotTransitionTime(int index, unsigned transitionTime)
Called when a transition time is seen.
virtual void gotAbbreviation(int index, const TQString &abbr)
Called when a timezone abbreviation is seen.
The KTimezoneSource class contains information source-dependent functions related to a timezone.
virtual bool parse(const TQString &zone, KTimezoneDetails &dataReceiver) const
Extract timezone detail information.
virtual TQString db()
Location of system timezone information.
The KTimezone class contains core functions related to a timezone.
float latitude() const
Returns the latitude of the timezone.
static bool isValidLatitude(float latitude)
A test for a valid latitude.
TQDateTime convert(const KTimezone *newZone, const TQDateTime &dateTime) const
Convert a date/time (which is interpreted as being localtime in this timezone) into localtime in the ...
float longitude() const
Returns the latitude of the timezone.
TQString name() const
Returns the name of the timezone.
TQString comment() const
Returns any comment for the timezone.
static bool isValidLongitude(float longitude)
A test for a valid longitude.
static const float UNKNOWN
A representation for unknown locations; this is a float that does not represent a real latitude or lo...
KTimezone(TDESharedPtr< KTimezoneSource > db, const TQString &name, const TQString &countryCode=TQString(), float latitude=UNKNOWN, float longitude=UNKNOWN, const TQString &comment=TQString())
Create a timezone.
TQString countryCode() const
Returns the two-letter country code of the timezone.
bool parse(KTimezoneDetails &dataReceiver) const
Extract timezone detail information.
int offset(TQt::TimeSpec basisSpec=TQt::UTC) const
Returns the current offset of this timezone to UTC or the local timezone in seconds.
const KTimezone * local()
Returns the local timezone.
const KTimezone * zone(const TQString &name)
Returns the given timezone.
void add(KTimezone *zone)
Add user-defined timezone to database.
const ZoneMap allZones()
Return timezone database.
@ Block
The application is suspended until the started process is finished.
kndbgstream & endl(kndbgstream &s)
Does nothing.