Skip to content

Commit

Permalink
Add RruleOption parsing in particular location
Browse files Browse the repository at this point in the history
  • Loading branch information
Egor Gorbunov committed May 24, 2018
1 parent fb08505 commit 752a9bf
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
26 changes: 24 additions & 2 deletions str.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,28 @@ import (
const (
// DateTimeFormat is date-time format used in iCalendar (RFC 5545)
DateTimeFormat = "20060102T150405Z"
// LocalDateTimeFormat is a date-time format without Z prefix
LocalDateTimeFormat = "20060102T150405"
// DateFormat is date format used in iCalendar (RFC 5545)
DateFormat = "20060102"
)

func timeToStr(time time.Time) string {
return time.UTC().Format(DateTimeFormat)
}

func strToTime(str string) (time.Time, error) {
return strToTimeInLoc(str, time.UTC)
}

func strToTimeInLoc(str string, loc *time.Location) (time.Time, error) {
if len(str) == len(DateFormat) {
return time.ParseInLocation(DateFormat, str, loc)
}
if len(str) == len(LocalDateTimeFormat) {
return time.ParseInLocation(LocalDateTimeFormat, str, loc)
}
// date-time format carries zone info
return time.Parse(DateTimeFormat, str)
}

Expand Down Expand Up @@ -143,6 +158,13 @@ func (option *ROption) String() string {

// StrToROption converts string to ROption
func StrToROption(rfcString string) (*ROption, error) {
return StrToROptionInLocation(rfcString, time.UTC)
}

// StrToROptionInLocation is same as StrToROption but in case local
// time is supplied as date-time/date field (ex. UNTIL), it is parsed
// as a time in a given location (time zone)
func StrToROptionInLocation(rfcString string, loc *time.Location) (*ROption, error) {
rfcString = strings.TrimSpace(rfcString)
if len(rfcString) == 0 {
return nil, errors.New("empty string")
Expand All @@ -162,15 +184,15 @@ func StrToROption(rfcString string) (*ROption, error) {
case "FREQ":
result.Freq, e = strToFreq(value)
case "DTSTART":
result.Dtstart, e = strToTime(value)
result.Dtstart, e = strToTimeInLoc(value, loc)
case "INTERVAL":
result.Interval, e = strconv.Atoi(value)
case "WKST":
result.Wkst, e = strToWeekday(value)
case "COUNT":
result.Count, e = strconv.Atoi(value)
case "UNTIL":
result.Until, e = strToTime(value)
result.Until, e = strToTimeInLoc(value, loc)
case "BYSETPOS":
result.Bysetpos, e = strToInts(value)
case "BYMONTH":
Expand Down
8 changes: 6 additions & 2 deletions str_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func TestInvalidString(t *testing.T) {
func TestSetStr(t *testing.T) {
setStr := "RRULE:FREQ=DAILY;UNTIL=20180517T235959Z\n" +
"RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,TU\n" +
"RRULE:FREQ=MONTHLY;UNTIL=20180520;BYMONTHDAY=1,2,3\n" +
"EXRULE:FREQ=WEEKLY;INTERVAL=4;BYDAY=MO\n" +
"EXDATE;VALUE=DATE-TIME:20180525T070000Z,20180530T130000Z\n" +
"RDATE;VALUE=DATE-TIME:20180801T131313Z,20180902T141414Z\n"
Expand All @@ -45,15 +46,18 @@ func TestSetStr(t *testing.T) {

// matching parsed RRules
rRules := set.GetRRule()
if len(rRules) != 2 {
t.Errorf("Unexpected number of rrule parsed: %v != 2, rrules: %v", len(rRules), rRules)
if len(rRules) != 3 {
t.Errorf("Unexpected number of rrule parsed: %v != 3, rrules: %v", len(rRules), rRules)
}
if rRules[0].String() != "FREQ=DAILY;UNTIL=20180517T235959Z" {
t.Errorf("Unexpected rrule: %s", rRules[0].String())
}
if rRules[1].String() != "FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,TU" {
t.Errorf("Unexpected rrule: %s", rRules[0].String())
}
if rRules[2].String() != "FREQ=MONTHLY;UNTIL=20180520T000000Z;BYMONTHDAY=1,2,3" {
t.Errorf("Unexpected rrule: %s", rRules[2].String())
}

// matching parsed EXRules
exRules := set.GetExRule()
Expand Down

0 comments on commit 752a9bf

Please sign in to comment.