summaryrefslogtreecommitdiff
path: root/library/backend/event.cpp
Unidiff
Diffstat (limited to 'library/backend/event.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/backend/event.cpp830
1 files changed, 830 insertions, 0 deletions
diff --git a/library/backend/event.cpp b/library/backend/event.cpp
new file mode 100644
index 0000000..50a663d
--- a/dev/null
+++ b/library/backend/event.cpp
@@ -0,0 +1,830 @@
1/**********************************************************************
2** Copyright (C) 2001 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "event.h"
22#include "qfiledirect_p.h"
23#include <qpe/timeconversion.h>
24#include <qpe/stringutil.h>
25#include <qpe/recordfields.h>
26#include <qbuffer.h>
27#include <time.h>
28#include "vobject_p.h"
29
30#include <stdio.h>
31
32using namespace Qtopia;
33
34static void write( QString& buf, const Event::RepeatPattern &r )
35{
36 buf += " rtype=\"";
37 switch ( r.type ) {
38 case Event::Daily:
39 buf += "Daily";
40 break;
41 case Event::Weekly:
42 buf += "Weekly";
43 break;
44 case Event::MonthlyDay:
45 buf += "MonthlyDay";
46 break;
47 case Event::MonthlyDate:
48 buf += "MonthlyDate";
49 break;
50 case Event::Yearly:
51 buf += "Yearly";
52 break;
53 default:
54 buf += "NoRepeat";
55 break;
56 }
57 buf += "\"";
58 if ( r.days > 0 )
59 buf += " rweekdays=\"" + QString::number( static_cast<int>( r.days ) ) + "\"";
60 if ( r.position != 0 )
61 buf += " rposition=\"" + QString::number( r.position ) + "\"";
62
63 buf += " rfreq=\"" + QString::number( r.frequency ) + "\"";
64 buf += " rhasenddate=\"" + QString::number( static_cast<int>( r.hasEndDate ) ) + "\"";
65 if ( r.hasEndDate )
66 buf += " enddt=\""
67 + QString::number( r.endDateUTC ? r.endDateUTC : time( 0 ) )
68 + "\"";
69 buf += " created=\"" + QString::number( r.createTime ) + "\"";
70}
71
72Qtopia::UidGen Event::sUidGen( Qtopia::UidGen::Qtopia );
73
74Event::Event() : Record()
75{
76 startUTC = endUTC = time( 0 );
77 typ = Normal;
78 hAlarm = FALSE;
79 hRepeat = FALSE;
80 aMinutes = 0;
81 aSound = Silent;
82 pattern.type = NoRepeat;
83 pattern.frequency = -1;
84}
85
86Event::Event( const QMap<int, QString> &map )
87{
88 setDescription( map[DatebookDescription] );
89 setLocation( map[Location] );
90 setCategories( idsFromString( map[DatebookCategory] ) );
91 setTimeZone( map[TimeZone] );
92 setNotes( map[Note] );
93 setStart( TimeConversion::fromUTC( map[StartDateTime].toUInt() ) );
94 setEnd( TimeConversion::fromUTC( map[EndDateTime].toUInt() ) );
95 setType( (Event::Type) map[DatebookType].toInt() );
96 setAlarm( ( map[HasAlarm] == "1" ? TRUE : FALSE ), map[AlarmTime].toInt(), (Event::SoundTypeChoice)map[SoundType].toInt() );
97 Event::RepeatPattern p;
98 p.type = (Event::RepeatType) map[ RepeatPatternType ].toInt();
99 p.frequency = map[ RepeatPatternFrequency ].toInt();
100 p.position = map[ RepeatPatternPosition ].toInt();
101 p.days = map[ RepeatPatternDays ].toInt();
102 p.hasEndDate = map[ RepeatPatternHasEndDate ].toInt();
103 p.endDateUTC = map[ RepeatPatternEndDate ].toUInt();
104 setRepeat( p );
105
106 setUid( map[ DatebookUid ].toInt() );
107}
108
109Event::~Event()
110{
111}
112
113int Event::week( const QDate& date )
114{
115 // Calculates the week this date is in within that
116 // month. Equals the "row" is is in in the month view
117 int week = 1;
118 QDate tmp( date.year(), date.month(), 1 );
119
120 if ( date.dayOfWeek() < tmp.dayOfWeek() )
121 ++week;
122
123 week += ( date.day() - 1 ) / 7;
124 return week;
125}
126
127int Event::occurrence( const QDate& date )
128{
129 // calculates the number of occurrances of this day of the
130 // week till the given date (e.g 3rd Wednesday of the month)
131 return ( date.day() - 1 ) / 7 + 1;
132}
133
134int Event::dayOfWeek( char day )
135{
136 int dayOfWeek = 1;
137 char i = Event::MON;
138 while ( !( i & day ) && i <= Event::SUN ) {
139 i <<= 1;
140 ++dayOfWeek;
141 }
142 return dayOfWeek;
143}
144
145int Event::monthDiff( const QDate& first, const QDate& second )
146{
147 return ( second.year() - first.year() ) * 12 +
148 second.month() - first.month();
149}
150
151QMap<int, QString> Event::toMap() const
152{
153 QMap<int, QString> m;
154 m.insert( DatebookDescription, description() );
155 m.insert ( Location, location() );
156 m.insert ( DatebookCategory, idsToString( categories() ) );
157 m.insert ( TimeZone, timeZone() );
158 m.insert ( Note, notes() );
159 m.insert ( StartDateTime, QString::number( TimeConversion::toUTC( start() ) ) );
160 m.insert ( EndDateTime, QString::number( TimeConversion::toUTC( end() ) ) );
161 m.insert ( DatebookType, QString::number( (int)type() ) );
162 m.insert ( HasAlarm, ( hasAlarm() ? "1" : "0" ) );
163 m.insert ( SoundType, QString::number( (int)alarmSound() ) );
164 m.insert ( AlarmTime, QString::number( alarmTime() ) );
165 m.insert ( RepeatPatternType, QString::number( static_cast<int>( repeatPattern().type ) ) );
166 m.insert ( RepeatPatternFrequency, QString::number( repeatPattern().frequency ) );
167 m.insert ( RepeatPatternPosition, QString::number( repeatPattern().position ) );
168 m.insert ( RepeatPatternDays, QString::number( repeatPattern().days ) );
169 m.insert ( RepeatPatternHasEndDate, QString::number( static_cast<int>( repeatPattern().hasEndDate ) ) );
170 m.insert ( RepeatPatternEndDate, QString::number( repeatPattern().endDateUTC ) );
171
172 m.insert( DatebookUid, QString::number( uid()) );
173
174 return m;
175}
176
177void Event::setRepeat( const RepeatPattern &p )
178{
179 setRepeat( p.type != NoRepeat, p );
180}
181
182void Event::setDescription( const QString &s )
183{
184 descript = s;
185}
186
187void Event::setLocation( const QString &s )
188{
189 locat = s;
190}
191
192// void Event::setCategory( const QString &s )
193// {
194// categ = s;
195// }
196
197void Event::setType( Type t )
198{
199 typ = t;
200}
201
202void Event::setStart( const QDateTime &d )
203{
204 startUTC = TimeConversion::toUTC( d );
205}
206
207void Event::setStart( time_t time )
208{
209 startUTC = time;
210}
211
212void Event::setEnd( const QDateTime &d )
213{
214 endUTC = TimeConversion::toUTC( d );
215}
216
217void Event::setEnd( time_t time )
218{
219 endUTC = time;
220}
221
222void Event::setTimeZone( const QString &z )
223{
224 tz = z;
225}
226
227void Event::setAlarm( bool b, int minutes, SoundTypeChoice s )
228{
229 hAlarm = b;
230 aMinutes = minutes;
231 aSound = s;
232}
233
234void Event::setRepeat( bool b, const RepeatPattern &p )
235{
236 hRepeat = b;
237 pattern = p;
238}
239
240void Event::setNotes( const QString &n )
241{
242 note = n;
243}
244
245const QString &Event::description() const
246{
247 return descript;
248}
249
250const QString &Event::location() const
251{
252 return locat;
253}
254
255// QString Event::category() const
256// {
257// return categ;
258// }
259
260Event::Type Event::type() const
261{
262 return typ;
263}
264
265QDateTime Event::start( bool actual ) const
266{
267 QDateTime dt = (startUTC > 0) ? TimeConversion::fromUTC( startUTC ) : QDateTime::currentDateTime();
268
269 if ( actual && typ == AllDay ) {
270 QTime t = dt.time();
271 t.setHMS( 0, 0, 0 );
272 dt.setTime( t );
273 }
274 return dt;
275}
276
277QDateTime Event::end( bool actual ) const
278{
279 QDateTime dt = (endUTC > 0) ? TimeConversion::fromUTC( endUTC ) : QDateTime::currentDateTime();
280
281 if ( actual && typ == AllDay ) {
282 QTime t = dt.time();
283 t.setHMS( 23, 59, 59 );
284 dt.setTime( t );
285 }
286 return dt;
287}
288
289const QString &Event::timeZone() const
290{
291 return tz;
292}
293
294bool Event::hasAlarm() const
295{
296 return hAlarm;
297}
298
299int Event::alarmTime() const
300{
301 return aMinutes;
302}
303
304Event::SoundTypeChoice Event::alarmSound() const
305{
306 return aSound;
307}
308
309bool Event::hasRepeat() const
310{
311 return doRepeat();
312}
313
314const Event::RepeatPattern &Event::repeatPattern() const
315{
316 return pattern;
317}
318
319Event::RepeatPattern &Event::repeatPattern()
320{
321 return pattern;
322}
323
324const QString &Event::notes() const
325{
326 return note;
327}
328
329bool Event::operator==( const Event &e ) const
330{
331 return ( e.descript == descript &&
332 e.locat == locat &&
333 e.categ == categ &&
334 e.typ == typ &&
335 e.startUTC == startUTC &&
336 e.endUTC == endUTC &&
337 e.tz == tz &&
338 e.hAlarm == hAlarm &&
339 e.aMinutes == aMinutes &&
340 e.aSound == aSound &&
341 e.hRepeat == hRepeat &&
342 e.pattern == pattern &&
343 e.note == note );
344}
345
346void Event::save( QString& buf )
347{
348 buf += " description=\"" + Qtopia::escapeString(descript) + "\"";
349 if ( !locat.isEmpty() )
350 buf += " location=\"" + Qtopia::escapeString(locat) + "\"";
351 // save the categoies differently....
352 QString strCats = idsToString( categories() );
353 buf += " categories=\"" + Qtopia::escapeString(strCats) + "\"";
354 buf += " uid=\"" + QString::number( uid() ) + "\"";
355 if ( (Type)typ != Normal )
356 buf += " type=\"AllDay\"";
357 if ( hAlarm ) {
358 buf += " alarm=\"" + QString::number( aMinutes ) + "\" sound=\"";
359 if ( aSound == Event::Loud )
360 buf += "loud";
361 else
362 buf += "silent";
363 buf += "\"";
364 }
365 if ( hRepeat )
366 write( buf, pattern );
367
368 buf += " start=\""
369 + QString::number( startUTC )
370 + "\"";
371
372 buf += " end=\""
373 + QString::number( endUTC )
374 + "\"";
375
376 if ( !note.isEmpty() )
377 buf += " note=\"" + Qtopia::escapeString( note ) + "\"";
378 buf += customToXml();
379}
380
381bool Event::RepeatPattern::operator==( const Event::RepeatPattern &right ) const
382{
383 // *sigh*
384 return ( type == right.type
385 && frequency == right.frequency
386 && position == right.position
387 && days == right.days
388 && hasEndDate == right.hasEndDate
389 && endDateUTC == right.endDateUTC
390 && createTime == right.createTime );
391}
392
393
394class EffectiveEventPrivate
395{
396public:
397 //currently the existence of the d pointer means multi-day repeating,
398 //msut be changed if we use the d pointer for anything else.
399 QDate startDate;
400 QDate endDate;
401};
402
403
404EffectiveEvent::EffectiveEvent()
405{
406 mDate = QDate::currentDate();
407 mStart = mEnd = QTime::currentTime();
408 d = 0;
409}
410
411EffectiveEvent::EffectiveEvent( const Event &e, const QDate &date, Position pos )
412{
413 mEvent = e;
414 mDate = date;
415 if ( pos & Start )
416 mStart = e.start( TRUE ).time();
417 else
418 mStart = QTime( 0, 0, 0 );
419
420 if ( pos & End )
421 mEnd = e.end( TRUE ).time();
422 else
423 mEnd = QTime( 23, 59, 59 );
424 d = 0;
425}
426
427EffectiveEvent::~EffectiveEvent()
428{
429 delete d;
430}
431
432EffectiveEvent::EffectiveEvent( const EffectiveEvent &e )
433{
434 d = 0;
435 *this = e;
436}
437
438EffectiveEvent& EffectiveEvent::operator=( const EffectiveEvent & e )
439{
440 if ( &e == this )
441 return *this;
442 delete d;
443 if ( e.d ) {
444 d = new EffectiveEventPrivate;
445 d->startDate = e.d->startDate;
446 d->endDate = e.d->endDate;
447 } else {
448 d = 0;
449 }
450 mEvent = e.mEvent;
451 mDate = e.mDate;
452 mStart = e.mStart;
453 mEnd = e.mEnd;
454
455 return *this;
456
457}
458
459// QString EffectiveEvent::category() const
460// {
461// return mEvent.category();
462// }
463
464const QString &EffectiveEvent::description( ) const
465{
466 return mEvent.description();
467}
468
469const QString &EffectiveEvent::location( ) const
470{
471 return mEvent.location();
472}
473
474const QString &EffectiveEvent::notes() const
475{
476 return mEvent.notes();
477}
478
479const Event &EffectiveEvent::event() const
480{
481 return mEvent;
482}
483
484const QTime &EffectiveEvent::end() const
485{
486 return mEnd;
487}
488
489const QTime &EffectiveEvent::start() const
490{
491 return mStart;
492}
493
494const QDate &EffectiveEvent::date() const
495{
496 return mDate;
497}
498
499int EffectiveEvent::length() const
500{
501 return (mEnd.hour() * 60 - mStart.hour() * 60)
502 + QABS(mStart.minute() - mEnd.minute() );
503}
504
505void EffectiveEvent::setDate( const QDate &dt )
506{
507 mDate = dt;
508}
509
510void EffectiveEvent::setStart( const QTime &start )
511{
512 mStart = start;
513}
514
515void EffectiveEvent::setEnd( const QTime &end )
516{
517 mEnd = end;
518}
519
520void EffectiveEvent::setEvent( Event e )
521{
522 mEvent = e;
523}
524
525bool EffectiveEvent::operator<( const EffectiveEvent &e ) const
526{
527 if ( mDate < e.date() )
528 return TRUE;
529 if ( mDate == e.date() )
530 return ( mStart < e.start() );
531 else
532 return FALSE;
533}
534
535bool EffectiveEvent::operator<=( const EffectiveEvent &e ) const
536{
537 return (mDate <= e.date() );
538}
539
540bool EffectiveEvent::operator==( const EffectiveEvent &e ) const
541{
542 return ( mDate == e.date()
543 && mStart == e.start()
544 && mEnd == e.end()
545 && mEvent == e.event() );
546}
547
548bool EffectiveEvent::operator!=( const EffectiveEvent &e ) const
549{
550 return !(*this == e);
551}
552
553bool EffectiveEvent::operator>( const EffectiveEvent &e ) const
554{
555 return !(*this <= e );
556}
557
558bool EffectiveEvent::operator>=(const EffectiveEvent &e) const
559{
560 return !(*this < e);
561}
562
563void EffectiveEvent::setEffectiveDates( const QDate &from, const QDate &to )
564{
565 if ( !from.isValid() ) {
566 delete d;
567 d = 0;
568 return;
569 }
570 if ( !d )
571 d = new EffectiveEventPrivate;
572 d->startDate = from;
573 d->endDate = to;
574}
575
576QDate EffectiveEvent::startDate() const
577{
578 if ( d )
579 return d->startDate;
580 else if ( mEvent.hasRepeat() )
581 return mDate; // single day, since multi-day should have a d pointer
582 else
583 return mEvent.start().date();
584}
585
586QDate EffectiveEvent::endDate() const
587{
588 if ( d )
589 return d->endDate;
590 else if ( mEvent.hasRepeat() )
591 return mDate; // single day, since multi-day should have a d pointer
592 else
593 return mEvent.end().date();
594}
595
596int EffectiveEvent::size() const
597{
598 return ( mEnd.hour() - mStart.hour() ) * 3600
599 + (mEnd.minute() - mStart.minute() * 60
600 + mEnd.second() - mStart.second() );
601}
602
603
604// vcal conversion code
605static inline VObject *safeAddPropValue( VObject *o, const char *prop, const QString &value )
606{
607 VObject *ret = 0;
608 if ( o && !value.isEmpty() )
609 ret = addPropValue( o, prop, value.latin1() );
610 return ret;
611}
612
613static inline VObject *safeAddProp( VObject *o, const char *prop)
614{
615 VObject *ret = 0;
616 if ( o )
617 ret = addProp( o, prop );
618 return ret;
619}
620
621static VObject *createVObject( const Event &e )
622{
623 VObject *vcal = newVObject( VCCalProp );
624 safeAddPropValue( vcal, VCVersionProp, "1.0" );
625 VObject *event = safeAddProp( vcal, VCEventProp );
626
627 safeAddPropValue( event, VCDTstartProp, TimeConversion::toISO8601( e.start() ) );
628 safeAddPropValue( event, VCDTendProp, TimeConversion::toISO8601( e.end() ) );
629 safeAddPropValue( event, "X-Qtopia-NOTES", e.description() );
630 safeAddPropValue( event, VCDescriptionProp, e.description() );
631 safeAddPropValue( event, VCLocationProp, e.location() );
632
633 if ( e.hasAlarm() ) {
634 VObject *alarm = safeAddProp( event, VCAAlarmProp );
635 QDateTime dt = e.start();
636 dt = dt.addSecs( -e.alarmTime()*60 );
637 safeAddPropValue( alarm, VCRunTimeProp, TimeConversion::toISO8601( dt ) );
638 safeAddPropValue( alarm, VCAudioContentProp,
639 (e.alarmSound() == Event::Silent ? "silent" : "alarm" ) );
640 }
641
642 safeAddPropValue( event, "X-Qtopia-TIMEZONE", e.timeZone() );
643
644 if ( e.type() == Event::AllDay )
645 safeAddPropValue( event, "X-Qtopia-AllDay", e.timeZone() );
646
647 // ### repeat missing
648
649 // ### categories missing
650
651 return vcal;
652}
653
654
655static Event parseVObject( VObject *obj )
656{
657 Event e;
658
659 bool haveAlarm = FALSE;
660 bool haveStart = FALSE;
661 bool haveEnd = FALSE;
662 QDateTime alarmTime;
663 Event::SoundTypeChoice soundType = Event::Silent;
664
665 VObjectIterator it;
666 initPropIterator( &it, obj );
667 while( moreIteration( &it ) ) {
668 VObject *o = nextVObject( &it );
669 QCString name = vObjectName( o );
670 QCString value = vObjectStringZValue( o );
671 if ( name == VCDTstartProp ) {
672 e.setStart( TimeConversion::fromISO8601( value ) );
673 haveStart = TRUE;
674 }
675 else if ( name == VCDTendProp ) {
676 e.setEnd( TimeConversion::fromISO8601( value ) );
677 haveEnd = TRUE;
678 }
679 else if ( name == "X-Qtopia-NOTES" ) {
680 e.setNotes( value );
681 }
682 else if ( name == VCDescriptionProp ) {
683 e.setDescription( value );
684 }
685 else if ( name == VCLocationProp ) {
686 e.setLocation( value );
687 }
688 else if ( name == VCAudioContentProp ) {
689 haveAlarm = TRUE;
690 VObjectIterator nit;
691 initPropIterator( &nit, o );
692 while( moreIteration( &nit ) ) {
693 VObject *o = nextVObject( &nit );
694 QCString name = vObjectName( o );
695 QCString value = vObjectStringZValue( o );
696 if ( name == VCRunTimeProp )
697 alarmTime = TimeConversion::fromISO8601( value );
698 else if ( name == VCAudioContentProp ) {
699 if ( value == "silent" )
700 soundType = Event::Silent;
701 else
702 soundType = Event::Loud;
703 }
704 }
705 }
706 else if ( name == "X-Qtopia-TIMEZONE") {
707 e.setTimeZone( value );
708 }
709 else if ( name == "X-Qtopia-AllDay" ) {
710 e.setType( Event::AllDay );
711 }
712#if 0
713 else {
714 printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) );
715 VObjectIterator nit;
716 initPropIterator( &nit, o );
717 while( moreIteration( &nit ) ) {
718 VObject *o = nextVObject( &nit );
719 QCString name = vObjectName( o );
720 QString value = vObjectStringZValue( o );
721 printf(" subprop: %s = %s\n", name.data(), value.latin1() );
722 }
723 }
724#endif
725 }
726
727 if ( !haveStart && !haveEnd )
728 e.setStart( QDateTime::currentDateTime() );
729
730 if ( !haveEnd ) {
731 e.setType( Event::AllDay );
732 e.setEnd( e.start() );
733 }
734
735 if ( haveAlarm ) {
736 int minutes = alarmTime.secsTo( e.start() ) / 60;
737 e.setAlarm( TRUE, minutes, soundType );
738 }
739 return e;
740}
741
742
743
744void Event::writeVCalendar( const QString &filename, const QValueList<Event> &events)
745{
746 QFileDirect f( filename.utf8().data() );
747 if ( !f.open( IO_WriteOnly ) ) {
748 qWarning("Unable to open vcard write");
749 return;
750 }
751
752 QValueList<Event>::ConstIterator it;
753 for( it = events.begin(); it != events.end(); ++it ) {
754 VObject *obj = createVObject( *it );
755 writeVObject( f.directHandle() , obj );
756 cleanVObject( obj );
757 }
758
759 cleanStrTbl();
760}
761
762void Event::writeVCalendar( const QString &filename, const Event &event)
763{
764 QFileDirect f( filename.utf8().data() );
765 if ( !f.open( IO_WriteOnly ) ) {
766 qWarning("Unable to open vcard write");
767 return;
768 }
769
770 VObject *obj = createVObject( event );
771 writeVObject( f.directHandle() , obj );
772 cleanVObject( obj );
773
774 cleanStrTbl();
775}
776
777
778QValueList<Event> Event::readVCalendar( const QString &filename )
779{
780 VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() );
781
782 QValueList<Event> events;
783
784 while ( obj ) {
785 QCString name = vObjectName( obj );
786 if ( name == VCCalProp ) {
787 VObjectIterator nit;
788 initPropIterator( &nit, obj );
789 while( moreIteration( &nit ) ) {
790 VObject *o = nextVObject( &nit );
791 QCString name = vObjectName( o );
792 if ( name == VCEventProp )
793 events.append( parseVObject( o ) );
794 }
795 } else if ( name == VCEventProp ) {
796 // shouldn't happen, but just to be sure
797 events.append( parseVObject( obj ) );
798 }
799 VObject *t = obj;
800 obj = nextVObjectInList(obj);
801 cleanVObject( t );
802 }
803
804 return events;
805}
806
807bool Event::match( const QRegExp &r ) const
808{
809 bool returnMe;
810 returnMe = false;
811
812 if ( descript.find( r ) > -1 )
813 returnMe = true;
814 else if ( locat.find( r ) > -1 )
815 returnMe = true;
816 else if ( TimeConversion::fromUTC( startUTC ).toString().find( r ) > -1 )
817 returnMe = true;
818 else if ( TimeConversion::fromUTC( endUTC ).toString().find( r ) > -1 )
819 returnMe = true;
820 else if ( tz.find( r ) > -1 )
821 returnMe = true;
822 else if ( note.find( r ) > -1 )
823 returnMe = true;
824 else if ( doRepeat() ) {
825 if ( pattern.hasEndDate )
826 if ( TimeConversion::fromUTC( pattern.endDateUTC ).toString().find(r) > -1 )
827 returnMe = true;
828 }
829 return returnMe;
830}