Skip to content

IsInEvent functionality #70

Open
@Mereep

Description

@Mereep

Hi, I found this repo yesterday when brainstorming (yes, and GPT-Storming) for a general way to represent a allowance to unlock a door.

Given a valid iCal format, I now need a way to check if now falls into the calender event (true false). Is there an easy way to do so (I didn't see a command in the lib)? I do not have any prior experience with the format yet, so I cannot judge on the complexity and edgy cases for this.

idk if it helps, but this is what ChatGPT came up with (untested yet):
Edit: code built into my program, tested for intervals and simple dates (UTC and local time)

func (cal *ICalCalendar) IsIn(unixTimestamp uint64)  (res Result[bool]) {
	defer func() {
		if r := recover(); r != nil {
			res = ResultError[bool](
				fmt.Errorf("panic when checking for date in ical calendar: %v", r),
				ERROR_ICAL_ISIN_CHECK)
		}
	}()
	givenTime := time.Unix(int64(unixTimestamp), 0)
	errors := []error{}
	found := false
	for _, event := range cal.inst.Events() {
		start, err := event.GetStartAt()
		if err != nil {
			errors = append(errors, err)
			continue
		}

		end, err := event.GetEndAt()
		if err != nil {
			errors = append(errors, err)
			continue
		}

		duration := end.Sub(start)

		// Check non-recurring event
		if (givenTime.After(start) || givenTime.Unix() == start.Unix()) && (givenTime.Before(end) || givenTime.Unix() == end.Unix()) {
			found = true
			break
		}

		// Check recurring event
		PropRRule := event.GetProperty("RRULE")
		if PropRRule != nil {
			startStr := event.GetProperty("DTSTART").Value
			rruleStr := PropRRule.Value
			r, err := rrule.StrToRRule(fmt.Sprintf("DTSTART:%s\nRRULE:%s", startStr, rruleStr))
			if err != nil {
				errors = append(errors, err)
				continue
			}

			instances := r.Between(start, start.Add(1*time.Hour*24*365), true) // Limit search to 1 year ahead
			for _, instance := range instances {
				instanceEnd := instance.Add(duration)
				if (givenTime.After(instance) || givenTime.Unix() == instance.Unix()) && (givenTime.Before(instanceEnd) || givenTime.Unix() == instanceEnd.Unix()) {
					found = true
					break
				}
			}
		}
	}

	if len(errors) > 0 {
		return ResultWarning[bool](
			found,
			errors,
			ERROR_ICAL_CHECK,
		)
	}

	return ResultOk(found)
}

it should be able to handle interval events also. Any feedback on that?

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions