22#include "icaltimezones.h"
27 #include <libical/ical.h>
28 #include <libical/icaltimezone.h>
30#include <ksystemtimezone.h>
34#include <QtCore/QDateTime>
35#include <QtCore/QString>
36#include <QtCore/QList>
37#include <QtCore/QVector>
39#include <QtCore/QFile>
40#include <QtCore/QTextStream>
45static const int minRuleCount = 5;
46static const int minPhaseCount = 8;
49static QDateTime toQDateTime(
const icaltimetype &t )
51 return QDateTime( QDate( t.year, t.month, t.day ),
52 QTime( t.hour, t.minute, t.second ),
53 ( icaltime_is_utc( t ) ? Qt::UTC : Qt::LocalTime ) );
59static QDateTime MAX_DATE()
62 if ( !dt.isValid() ) {
63 dt = QDateTime( QDate::currentDate().addYears( 20 ), QTime( 0, 0, 0 ) );
68static icaltimetype writeLocalICalDateTime(
const QDateTime &utc,
int offset )
70 QDateTime local = utc.addSecs( offset );
71 icaltimetype t = icaltime_null_time();
72 t.year = local.date().year();
73 t.month = local.date().month();
74 t.day = local.date().day();
75 t.hour = local.time().hour();
76 t.minute = local.time().minute();
77 t.second = local.time().second();
88class ICalTimeZonesPrivate
91 ICalTimeZonesPrivate() {}
92 ICalTimeZones::ZoneMap zones;
97 : d( new ICalTimeZonesPrivate )
113 if ( !
zone.isValid() ) {
116 if ( d->zones.find(
zone.name() ) != d->zones.end() ) {
120 d->zones.insert(
zone.name(),
zone );
126 if (
zone.isValid() ) {
127 for ( ZoneMap::Iterator it = d->zones.begin(), end = d->zones.end(); it != end; ++it ) {
128 if ( it.value() ==
zone ) {
129 d->zones.erase( it );
139 if ( !name.isEmpty() ) {
140 ZoneMap::Iterator it = d->zones.find( name );
141 if ( it != d->zones.end() ) {
157 if ( !name.isEmpty() ) {
158 ZoneMap::ConstIterator it = d->zones.constFind( name );
159 if ( it != d->zones.constEnd() ) {
174 const QString &countryCode,
175 float latitude,
float longitude,
176 const QString &comment )
177 : KTimeZoneBackend( source, name, countryCode, latitude, longitude, comment )
181 : KTimeZoneBackend( 0, tz.name(), tz.countryCode(), tz.latitude(), tz.longitude(), tz.comment() )
183 Q_UNUSED( earliest );
186ICalTimeZoneBackend::~ICalTimeZoneBackend()
196 return "ICalTimeZone";
220 tz.latitude(), tz.longitude(),
223 const KTimeZoneData *data = tz.data(
true );
240 return dat ? dat->
city() : QString();
246 return dat ? dat->
url() : QByteArray();
258 return dat ? dat->
vtimezone() : QByteArray();
269 if ( !updateBase( other ) ) {
273 KTimeZoneData *otherData = other.data() ? other.data()->clone() : 0;
274 setData( otherData, other.source() );
281 if ( !utcZone.isValid() ) {
283 utcZone = tzs.
parse( icaltimezone_get_utc_timezone() );
291class ICalTimeZoneDataPrivate
294 ICalTimeZoneDataPrivate() : icalComponent(0) {}
295 ~ICalTimeZoneDataPrivate()
297 if ( icalComponent ) {
298 icalcomponent_free( icalComponent );
301 icalcomponent *component()
const {
return icalComponent; }
302 void setComponent( icalcomponent *c )
304 if ( icalComponent ) {
305 icalcomponent_free( icalComponent );
311 QDateTime lastModified;
313 icalcomponent *icalComponent;
318 : d ( new ICalTimeZoneDataPrivate() )
323 : KTimeZoneData( rhs ),
324 d( new ICalTimeZoneDataPrivate() )
326 d->location = rhs.d->location;
328 d->lastModified = rhs.d->lastModified;
329 d->setComponent( icalcomponent_new_clone( rhs.d->component() ) );
333 const KTimeZone &tz,
const QDate &earliest )
334 : KTimeZoneData( rhs ),
335 d( new ICalTimeZoneDataPrivate() )
340 WEEKDAY_OF_MONTH = 0x02,
341 LAST_WEEKDAY_OF_MONTH = 0x04
344 if ( tz.type() ==
"KSystemTimeZone" ) {
348 icalcomponent *c = 0;
349 KTimeZone ktz = KSystemTimeZones::readZone( tz.name() );
350 if ( ktz.isValid() ) {
351 if ( ktz.data(
true) ) {
353 icaltimezone *itz = icaltz.icalTimezone();
354 c = icalcomponent_new_clone( icaltimezone_get_component( itz ) );
355 icaltimezone_free( itz, 1 );
360 icaltimezone *itz = icaltimezone_get_builtin_timezone( tz.name().toUtf8() );
361 c = icalcomponent_new_clone( icaltimezone_get_component( itz ) );
367 icalproperty *prop = icalcomponent_get_first_property( c, ICAL_TZID_PROPERTY );
369 icalvalue *value = icalproperty_get_value( prop );
370 const char *tzid = icalvalue_get_text( value );
372 int len = icalprefix.size();
373 if ( !strncmp( icalprefix, tzid, len ) ) {
374 const char *s = strchr( tzid + len,
'/' );
376 QByteArray tzidShort( s + 1 );
377 icalvalue_set_text( value, tzidShort );
380 prop = icalcomponent_get_first_property( c, ICAL_X_PROPERTY );
381 const char *xname = icalproperty_get_x_name( prop );
382 if ( xname && !strcmp( xname,
"X-LIC-LOCATION" ) ) {
383 icalcomponent_remove_property( c, prop );
389 d->setComponent( c );
392 icalcomponent *tzcomp = icalcomponent_new(ICAL_VTIMEZONE_COMPONENT);
393 icalcomponent_add_property( tzcomp, icalproperty_new_tzid( tz.name().toUtf8() ) );
398 QList<KTimeZone::Transition> transits = transitions();
399 if ( earliest.isValid() ) {
401 for (
int i = 0, end = transits.count(); i < end; ++i ) {
402 if ( transits[i].time().date() >= earliest ) {
404 transits.erase( transits.begin(), transits.begin() + i );
410 int trcount = transits.count();
411 QVector<bool> transitionsDone(trcount);
412 transitionsDone.fill(
false);
416 icaldatetimeperiodtype dtperiod;
417 dtperiod.period = icalperiodtype_null_period();
420 for ( ; i < trcount && transitionsDone[i]; ++i ) {
423 if ( i >= trcount ) {
427 int preOffset = ( i > 0 ) ? transits[i - 1].phase().utcOffset() : rhs.previousUtcOffset();
428 KTimeZone::Phase phase = transits[i].phase();
429 if ( phase.utcOffset() == preOffset ) {
430 transitionsDone[i] =
true;
431 while ( ++i < trcount ) {
432 if ( transitionsDone[i] ||
433 transits[i].phase() != phase ||
434 transits[i - 1].phase().utcOffset() != preOffset ) {
437 transitionsDone[i] =
true;
441 icalcomponent *phaseComp =
442 icalcomponent_new( phase.isDst() ? ICAL_XDAYLIGHT_COMPONENT : ICAL_XSTANDARD_COMPONENT );
443 QList<QByteArray> abbrevs = phase.abbreviations();
444 for (
int a = 0, aend = abbrevs.count(); a < aend; ++a ) {
445 icalcomponent_add_property( phaseComp,
446 icalproperty_new_tzname(
447 static_cast<const char*
>( abbrevs[a]) ) );
449 if ( !phase.comment().isEmpty() ) {
450 icalcomponent_add_property( phaseComp,
451 icalproperty_new_comment( phase.comment().toUtf8() ) );
453 icalcomponent_add_property( phaseComp,
454 icalproperty_new_tzoffsetfrom( preOffset ) );
455 icalcomponent_add_property( phaseComp,
456 icalproperty_new_tzoffsetto( phase.utcOffset() ) );
458 icalcomponent *phaseComp1 = icalcomponent_new_clone( phaseComp );
459 icalcomponent_add_property( phaseComp1,
460 icalproperty_new_dtstart(
461 writeLocalICalDateTime( transits[i].time(), preOffset ) ) );
462 bool useNewRRULE =
false;
468 int year = 0, month = 0, daysInMonth = 0, dayOfMonth = 0;
470 int nthFromStart = 0;
474 QList<QDateTime> rdates;
475 QList<QDateTime> times;
476 QDateTime qdt = transits[i].time();
478 transitionsDone[i] =
true;
482 rule = DAY_OF_MONTH | WEEKDAY_OF_MONTH | LAST_WEEKDAY_OF_MONTH;
486 month = date.month();
487 daysInMonth = date.daysInMonth();
488 dayOfWeek = date.dayOfWeek();
489 dayOfMonth = date.day();
490 nthFromStart = ( dayOfMonth - 1 ) / 7 + 1;
491 nthFromEnd = ( daysInMonth - dayOfMonth ) / 7 + 1;
493 if ( ++i >= trcount ) {
495 times += QDateTime();
497 if ( transitionsDone[i] ||
498 transits[i].phase() != phase ||
499 transits[i - 1].phase().utcOffset() != preOffset ) {
502 transitionsDone[i] =
true;
503 qdt = transits[i].time();
504 if ( !qdt.isValid() ) {
510 if ( qdt.time() != time ||
511 date.month() != month ||
512 date.year() != ++year ) {
515 int day = date.day();
516 if ( ( newRule & DAY_OF_MONTH ) && day != dayOfMonth ) {
517 newRule &= ~DAY_OF_MONTH;
519 if ( newRule & ( WEEKDAY_OF_MONTH | LAST_WEEKDAY_OF_MONTH ) ) {
520 if ( date.dayOfWeek() != dayOfWeek ) {
521 newRule &= ~( WEEKDAY_OF_MONTH | LAST_WEEKDAY_OF_MONTH );
523 if ( ( newRule & WEEKDAY_OF_MONTH ) &&
524 ( day - 1 ) / 7 + 1 != nthFromStart ) {
525 newRule &= ~WEEKDAY_OF_MONTH;
527 if ( ( newRule & LAST_WEEKDAY_OF_MONTH ) &&
528 ( daysInMonth - day ) / 7 + 1 != nthFromEnd ) {
529 newRule &= ~LAST_WEEKDAY_OF_MONTH;
539 int yr = times[0].date().year();
540 while ( !rdates.isEmpty() ) {
543 if ( qdt.time() != time ||
544 date.month() != month ||
545 date.year() != --yr ) {
548 int day = date.day();
549 if ( rule & DAY_OF_MONTH ) {
550 if ( day != dayOfMonth ) {
554 if ( date.dayOfWeek() != dayOfWeek ||
555 ( ( rule & WEEKDAY_OF_MONTH ) &&
556 ( day - 1 ) / 7 + 1 != nthFromStart ) ||
557 ( ( rule & LAST_WEEKDAY_OF_MONTH ) &&
558 ( daysInMonth - day ) / 7 + 1 != nthFromEnd ) ) {
562 times.prepend( qdt );
565 if ( times.count() > ( useNewRRULE ? minPhaseCount : minRuleCount ) ) {
567 icalrecurrencetype r;
568 icalrecurrencetype_clear( &r );
569 r.freq = ICAL_YEARLY_RECURRENCE;
570 r.count = ( year >= 2030 ) ? 0 : times.count() - 1;
571 r.by_month[0] = month;
572 if ( rule & DAY_OF_MONTH ) {
573 r.by_month_day[0] = dayOfMonth;
574 }
else if ( rule & WEEKDAY_OF_MONTH ) {
575 r.by_day[0] = ( dayOfWeek % 7 + 1 ) + ( nthFromStart * 8 );
576 }
else if ( rule & LAST_WEEKDAY_OF_MONTH ) {
577 r.by_day[0] = -( dayOfWeek % 7 + 1 ) - ( nthFromEnd * 8 );
579 icalproperty *prop = icalproperty_new_rrule( r );
583 icalcomponent *c = icalcomponent_new_clone( phaseComp );
584 icalcomponent_add_property(
585 c, icalproperty_new_dtstart( writeLocalICalDateTime( times[0], preOffset ) ) );
586 icalcomponent_add_property( c, prop );
587 icalcomponent_add_component( tzcomp, c );
589 icalcomponent_add_property( phaseComp1, prop );
593 for (
int t = 0, tend = times.count() - 1; t < tend; ++t ) {
605 }
while ( i < trcount );
608 for (
int rd = 0, rdend = rdates.count(); rd < rdend; ++rd ) {
609 dtperiod.time = writeLocalICalDateTime( rdates[rd], preOffset );
610 icalcomponent_add_property( phaseComp1, icalproperty_new_rdate( dtperiod ) );
612 icalcomponent_add_component( tzcomp, phaseComp1 );
613 icalcomponent_free( phaseComp );
616 d->setComponent( tzcomp );
628 if ( &rhs ==
this ) {
632 KTimeZoneData::operator=( rhs );
633 d->location = rhs.d->location;
635 d->lastModified = rhs.d->lastModified;
636 d->setComponent( icalcomponent_new_clone( rhs.d->component() ) );
657 return d->lastModified;
662 QByteArray result( icalcomponent_as_ical_string( d->component() ) );
663 icalmemory_free_ring();
669 icaltimezone *icaltz = icaltimezone_new();
673 icalcomponent *c = icalcomponent_new_clone( d->component() );
674 if ( !icaltimezone_set_component( icaltz, c ) ) {
675 icalcomponent_free( c );
676 icaltimezone_free( icaltz, 1 );
690class ICalTimeZoneSourcePrivate
693 static QList<QDateTime> parsePhase( icalcomponent *,
bool daylight,
694 int &prevOffset, KTimeZone::Phase & );
695 static QByteArray icalTzidPrefix;
698QByteArray ICalTimeZoneSourcePrivate::icalTzidPrefix;
702 : KTimeZoneSource( false ),
713 QFile file( fileName );
714 if ( !file.open( QIODevice::ReadOnly ) ) {
717 QTextStream ts( &file );
718 ts.setCodec(
"ISO 8859-1" );
719 QByteArray text = ts.readAll().trimmed().toLatin1();
723 icalcomponent *calendar = icalcomponent_new_from_string( text.data() );
725 if ( icalcomponent_isa( calendar ) == ICAL_VCALENDAR_COMPONENT ) {
726 result =
parse( calendar, zones );
728 icalcomponent_free( calendar );
735 for ( icalcomponent *c = icalcomponent_get_first_component( calendar, ICAL_VTIMEZONE_COMPONENT );
736 c; c = icalcomponent_get_next_component( calendar, ICAL_VTIMEZONE_COMPONENT ) ) {
738 if ( !zone.isValid() ) {
742 if ( oldzone.isValid() ) {
746 }
else if ( !zones.
add( zone ) ) {
760 icalproperty *p = icalcomponent_get_first_property( vtimezone, ICAL_ANY_PROPERTY );
762 icalproperty_kind kind = icalproperty_isa( p );
765 case ICAL_TZID_PROPERTY:
766 name = QString::fromUtf8( icalproperty_get_tzid( p ) );
769 case ICAL_TZURL_PROPERTY:
770 data->d->url = icalproperty_get_tzurl( p );
773 case ICAL_LOCATION_PROPERTY:
775 data->d->location = QString::fromUtf8( icalproperty_get_location( p ) );
778 case ICAL_X_PROPERTY:
780 const char *xname = icalproperty_get_x_name( p );
781 if ( xname && !strcmp( xname,
"X-LIC-LOCATION" ) ) {
782 xlocation = QString::fromUtf8( icalproperty_get_x( p ) );
786 case ICAL_LASTMODIFIED_PROPERTY:
788 icaltimetype t = icalproperty_get_lastmodified(p);
789 if ( icaltime_is_utc( t ) ) {
790 data->d->lastModified = toQDateTime( t );
792 kDebug() <<
"LAST-MODIFIED not UTC";
799 p = icalcomponent_get_next_property( vtimezone, ICAL_ANY_PROPERTY );
802 if ( name.isEmpty() ) {
803 kDebug() <<
"TZID missing";
807 if ( data->d->location.isEmpty() && !xlocation.isEmpty() ) {
808 data->d->location = xlocation;
811 if ( name.startsWith( prefix ) ) {
813 int i = name.indexOf(
'/', prefix.length() );
815 name = name.mid( i + 1 );
825 QList<KTimeZone::Transition> transitions;
827 QList<KTimeZone::Phase> phases;
828 for ( icalcomponent *c = icalcomponent_get_first_component( vtimezone, ICAL_ANY_COMPONENT );
829 c; c = icalcomponent_get_next_component( vtimezone, ICAL_ANY_COMPONENT ) )
832 KTimeZone::Phase phase;
833 QList<QDateTime> times;
834 icalcomponent_kind kind = icalcomponent_isa( c );
837 case ICAL_XSTANDARD_COMPONENT:
839 times = ICalTimeZoneSourcePrivate::parsePhase( c,
false, prevoff, phase );
842 case ICAL_XDAYLIGHT_COMPONENT:
844 times = ICalTimeZoneSourcePrivate::parsePhase( c,
true, prevoff, phase );
848 kDebug() <<
"Unknown component:" << kind;
851 int tcount = times.count();
854 for (
int t = 0; t < tcount; ++t ) {
855 transitions += KTimeZone::Transition( times[t], phase );
857 if ( !earliest.isValid() || times[0] < earliest ) {
858 prevOffset = prevoff;
863 data->setPhases( phases, prevOffset );
866 qSort( transitions );
867 for (
int t = 1, tend = transitions.count(); t < tend; ) {
868 if ( transitions[t].phase() == transitions[t - 1].phase() ) {
869 transitions.removeAt( t );
875 data->setTransitions( transitions );
877 data->d->setComponent( icalcomponent_new_clone( vtimezone ) );
878 kDebug() <<
"VTIMEZONE" << name;
892QList<QDateTime> ICalTimeZoneSourcePrivate::parsePhase( icalcomponent *c,
895 KTimeZone::Phase &phase )
897 QList<QDateTime> transitions;
900 QList<QByteArray> abbrevs;
905 bool found_dtstart =
false;
906 bool found_tzoffsetfrom =
false;
907 bool found_tzoffsetto =
false;
908 icaltimetype dtstart = icaltime_null_time();
911 icalproperty *p = icalcomponent_get_first_property( c, ICAL_ANY_PROPERTY );
913 icalproperty_kind kind = icalproperty_isa( p );
916 case ICAL_TZNAME_PROPERTY:
922 QByteArray tzname = icalproperty_get_tzname( p );
925 if ( ( !daylight && tzname ==
"Standard Time" ) ||
926 ( daylight && tzname ==
"Daylight Time" ) ) {
929 if ( !abbrevs.contains( tzname ) ) {
934 case ICAL_DTSTART_PROPERTY:
935 dtstart = icalproperty_get_dtstart( p );
936 found_dtstart =
true;
939 case ICAL_TZOFFSETFROM_PROPERTY:
940 prevOffset = icalproperty_get_tzoffsetfrom( p );
941 found_tzoffsetfrom =
true;
944 case ICAL_TZOFFSETTO_PROPERTY:
945 utcOffset = icalproperty_get_tzoffsetto( p );
946 found_tzoffsetto =
true;
949 case ICAL_COMMENT_PROPERTY:
950 comment = QString::fromUtf8( icalproperty_get_comment( p ) );
953 case ICAL_RDATE_PROPERTY:
954 case ICAL_RRULE_PROPERTY:
959 kDebug() <<
"Unknown property:" << kind;
962 p = icalcomponent_get_next_property( c, ICAL_ANY_PROPERTY );
966 if ( !found_dtstart || !found_tzoffsetfrom || !found_tzoffsetto ) {
967 kDebug() <<
"DTSTART/TZOFFSETFROM/TZOFFSETTO missing";
972 QDateTime localStart = toQDateTime( dtstart );
973 dtstart.second -= prevOffset;
974 dtstart.zone = icaltimezone_get_utc_timezone();
975 QDateTime utcStart = toQDateTime( icaltime_normalize( dtstart ) );
977 transitions += utcStart;
984 KDateTime klocalStart( localStart, KDateTime::Spec::ClockTime() );
985 KDateTime maxTime( MAX_DATE(), KDateTime::Spec::ClockTime() );
987 icalproperty *p = icalcomponent_get_first_property( c, ICAL_ANY_PROPERTY );
989 icalproperty_kind kind = icalproperty_isa( p );
992 case ICAL_RDATE_PROPERTY:
994 icaltimetype t = icalproperty_get_rdate(p).time;
995 if ( icaltime_is_date( t ) ) {
997 t.hour = dtstart.hour;
998 t.minute = dtstart.minute;
999 t.second = dtstart.second;
1005 if ( !icaltime_is_utc( t ) ) {
1006 t.second -= prevOffset;
1007 t.zone = icaltimezone_get_utc_timezone();
1008 t = icaltime_normalize( t );
1010 transitions += toQDateTime( t );
1013 case ICAL_RRULE_PROPERTY:
1018 impl.readRecurrence( icalproperty_get_rrule( p ), &r );
1019 r.setStartDt( klocalStart );
1022 if ( r.duration() == 0 ) {
1023 KDateTime end( r.endDt() );
1024 if ( end.timeSpec() == KDateTime::Spec::UTC() ) {
1025 end.setTimeSpec( KDateTime::Spec::ClockTime() );
1026 r.setEndDt( end.addSecs( prevOffset ) );
1029 DateTimeList dts = r.timesInInterval( klocalStart, maxTime );
1030 for (
int i = 0, end = dts.count(); i < end; ++i ) {
1031 QDateTime utc = dts[i].dateTime();
1032 utc.setTimeSpec( Qt::UTC );
1033 transitions += utc.addSecs( -prevOffset );
1040 p = icalcomponent_get_next_property( c, ICAL_ANY_PROPERTY );
1042 qSortUnique( transitions );
1045 phase = KTimeZone::Phase( utcOffset, abbrevs, daylight, comment );
1052 if ( !icalBuiltIn ) {
1056 QString tzid = zone;
1058 if ( zone.startsWith( prefix ) ) {
1059 int i = zone.indexOf(
'/', prefix.length() );
1061 tzid = zone.mid( i + 1 );
1064 KTimeZone ktz = KSystemTimeZones::readZone( tzid );
1065 if ( ktz.isValid() ) {
1066 if ( ktz.data(
true ) ) {
1075 QByteArray zoneName = zone.toUtf8();
1076 icaltimezone *icaltz = icaltimezone_get_builtin_timezone( zoneName );
1079 icaltz = icaltimezone_get_builtin_timezone_from_tzid( zoneName );
1084 return parse( icaltz );
1089 if ( ICalTimeZoneSourcePrivate::icalTzidPrefix.isEmpty() ) {
1090 icaltimezone *icaltz = icaltimezone_get_builtin_timezone(
"Europe/London" );
1091 QByteArray tzid = icaltimezone_get_tzid( icaltz );
1092 if ( tzid.right( 13 ) ==
"Europe/London" ) {
1093 int i = tzid.indexOf(
'/', 1 );
1095 ICalTimeZoneSourcePrivate::icalTzidPrefix = tzid.left( i + 1 );
1096 return ICalTimeZoneSourcePrivate::icalTzidPrefix;
1099 kError() <<
"failed to get libical TZID prefix";
1101 return ICalTimeZoneSourcePrivate::icalTzidPrefix;
Backend class for KICalTimeZone class.
virtual bool hasTransitions(const KTimeZone *caller) const
Implements ICalTimeZone::hasTransitions().
ICalTimeZoneBackend()
Implements ICalTimeZone::ICalTimeZone().
virtual QByteArray type() const
Returns the class name of the data represented by this instance.
virtual KTimeZoneBackend * clone() const
Creates a copy of this instance.
Parsed iCalendar VTIMEZONE data.
ICalTimeZoneData()
Default constructor.
virtual ~ICalTimeZoneData()
Destructor.
QString city() const
Returns the name of the city for this time zone, if any.
virtual KTimeZoneData * clone() const
Creates a new copy of this object.
QByteArray url() const
Returns the URL of the published VTIMEZONE definition, if any.
QDateTime lastModified() const
Returns the LAST-MODIFIED time of the VTIMEZONE, if any.
QByteArray vtimezone() const
Returns the VTIMEZONE string which represents this time zone.
virtual bool hasTransitions() const
Return whether daylight saving transitions are available for the time zone.
ICalTimeZoneData & operator=(const ICalTimeZoneData &rhs)
Assignment operator.
icaltimezone * icalTimezone() const
Returns the ICal timezone structure which represents this time zone.
A class which reads and parses iCalendar VTIMEZONE components, and accesses libical time zone data.
ICalTimeZone parse(icalcomponent *vtimezone)
Creates an ICalTimeZone instance containing the detailed information parsed from a VTIMEZONE componen...
ICalTimeZoneSource()
Constructs an iCalendar time zone source.
static QByteArray icalTzidPrefix()
Returns the prefix string used in the TZID field in built-in libical time zones.
ICalTimeZone standardZone(const QString &zone, bool icalBuiltIn=false)
Creates an ICalTimeZone instance for a standard time zone.
virtual ~ICalTimeZoneSource()
Destructor.
The ICalTimeZone class represents an iCalendar VTIMEZONE component.
QString city() const
Returns the name of the city for this time zone, if any.
ICalTimeZone()
Constructs a null time zone.
QByteArray url() const
Returns the URL of the published VTIMEZONE definition, if any.
icaltimezone * icalTimezone() const
Returns the ICal timezone structure which represents this time zone.
static ICalTimeZone utc()
Returns a standard UTC time zone, with name "UTC".
QByteArray vtimezone() const
Returns the VTIMEZONE string which represents this time zone.
QDateTime lastModified() const
Returns the LAST-MODIFIED time of the VTIMEZONE, if any.
virtual ~ICalTimeZone()
Destructor.
bool update(const ICalTimeZone &other)
Update the definition of the time zone to be identical to another ICalTimeZone instance.
The ICalTimeZones class represents a time zone database which consists of a collection of individual ...
ICalTimeZones()
Constructs an empty time zone collection.
const ZoneMap zones() const
Returns all the time zones defined in this collection.
~ICalTimeZones()
Destructor.
void clear()
Clears the collection.
ICalTimeZone remove(const ICalTimeZone &zone)
Removes a time zone from the collection.
ICalTimeZone zone(const QString &name) const
Returns the time zone with the given name.
bool add(const ICalTimeZone &zone)
Adds a time zone to the collection.
This class represents a recurrence rule for a calendar incidence.
This class represents a recurrence rule for a calendar incidence.
A QList which can be sorted.