@@ -10,6 +10,7 @@ import (
1010 "strings"
1111 "sync"
1212 "time"
13+ "github.com/ChannelMeter/iso8601duration"
1314)
1415
1516func init () {
@@ -281,6 +282,12 @@ func (p *Parser) parseEvents(cal *Calendar, eventsData []string) {
281282
282283 start := p .parseEventStart (eventData )
283284 end := p .parseEventEnd (eventData )
285+
286+ duration := p .parseEventDuration (eventData )
287+ if end .Before (start ) {
288+ end = start .Add (duration )
289+ }
290+
284291 // whole day event when both times are 00:00:00
285292 wholeDay := start .Hour () == 0 && end .Hour () == 0 && start .Minute () == 0 && end .Minute () == 0 && start .Second () == 0 && end .Second () == 0
286293
@@ -518,55 +525,73 @@ func (p *Parser) parseEventModified(eventData string) time.Time {
518525 return t
519526}
520527
528+ func parseDateTime (str string ) time.Time {
529+ if ! strings .Contains (str , "Z" ) {
530+ str = fmt .Sprintf ("%sZ" , str )
531+ }
532+
533+ t , _ := time .Parse (IcsFormat , str )
534+ return t
535+ }
536+
521537// parses the event start time
522538func (p * Parser ) parseEventStart (eventData string ) time.Time {
523539 reWholeDay , _ := regexp .Compile (`DTSTART;VALUE=DATE:.*?\n` )
524540 re , _ := regexp .Compile (`DTSTART(;TZID=.*?){0,1}:.*?\n` )
525- resultWholeDay := reWholeDay .FindString (eventData )
526- var t time.Time
541+ reDateTime , _ := regexp .Compile (`DTSTART;VALUE=DATE-TIME:.*?\n` )
527542
528- if resultWholeDay != "" {
543+ if resultWholeDay := reWholeDay . FindString ( eventData ); resultWholeDay != "" {
529544 // whole day event
530545 modified := trimField (resultWholeDay , "DTSTART;VALUE=DATE:" )
531- t , _ = time .Parse (IcsFormatWholeDay , modified )
532- } else {
533- // event that has start hour and minute
534- result := re .FindString (eventData )
535- modified := trimField (result , "DTSTART(;TZID=.*?){0,1}:" )
536-
537- if ! strings .Contains (modified , "Z" ) {
538- modified = fmt .Sprintf ("%sZ" , modified )
539- }
540-
541- t , _ = time .Parse (IcsFormat , modified )
546+ t , _ := time .Parse (IcsFormatWholeDay , modified )
547+ return t
542548 }
543-
544- return t
549+ if resultDateTime := reDateTime .FindString (eventData ); resultDateTime != "" {
550+ // date time event
551+ modified := trimField (resultDateTime , "DTSTART;VALUE=DATE-TIME:" )
552+ return parseDateTime (modified )
553+ }
554+ // event that has start hour and minute
555+ result := re .FindString (eventData )
556+ modified := trimField (result , "DTSTART(;TZID=.*?){0,1}:" )
557+ return parseDateTime (modified )
545558}
546559
547560// parses the event end time
548561func (p * Parser ) parseEventEnd (eventData string ) time.Time {
549562 reWholeDay , _ := regexp .Compile (`DTEND;VALUE=DATE:.*?\n` )
550563 re , _ := regexp .Compile (`DTEND(;TZID=.*?){0,1}:.*?\n` )
551- resultWholeDay := reWholeDay .FindString (eventData )
552- var t time.Time
564+ reDateTime , _ := regexp .Compile (`DTEND;VALUE=DATE-TIME:.*?\n` )
553565
554- if resultWholeDay != "" {
566+ if resultWholeDay := reWholeDay . FindString ( eventData ); resultWholeDay != "" {
555567 // whole day event
556568 modified := trimField (resultWholeDay , "DTEND;VALUE=DATE:" )
557- t , _ = time .Parse (IcsFormatWholeDay , modified )
558- } else {
559- // event that has end hour and minute
560- result := re .FindString (eventData )
561- modified := trimField (result , "DTEND(;TZID=.*?){0,1}:" )
562-
563- if ! strings .Contains (modified , "Z" ) {
564- modified = fmt .Sprintf ("%sZ" , modified )
565- }
566- t , _ = time .Parse (IcsFormat , modified )
569+ t , _ := time .Parse (IcsFormatWholeDay , modified )
570+ return t
571+ }
572+ if resultDateTime := reDateTime .FindString (eventData ); resultDateTime != "" {
573+ // date time event
574+ modified := trimField (resultDateTime , "DTEND;VALUE=DATE-TIME:" )
575+ return parseDateTime (modified )
576+ }
577+ // event that has end hour and minute
578+ result := re .FindString (eventData )
579+ modified := trimField (result , "DTEND(;TZID=.*?){0,1}:" )
580+ return parseDateTime (modified )
581+ }
582+
583+ func (p * Parser ) parseEventDuration (eventData string ) time.Duration {
584+ reDuration , _ := regexp .Compile (`DURATION:.*?\n` )
585+ result := reDuration .FindString (eventData )
586+ trimmed := trimField (result , "DURATION:" )
587+ parsedDuration , err := duration .FromString (trimmed )
588+ var output time.Duration
589+
590+ if err == nil {
591+ output = parsedDuration .ToDuration ()
567592 }
568- return t
569593
594+ return output
570595}
571596
572597// parses the event RRULE (the repeater)
0 commit comments