rossta / montrose

Recurring events library for Ruby. Enumerable recurrence objects and convenient chainable interface.
https://rossta.net/montrose/
MIT License
842 stars 52 forks source link

include? somehow does not include - and loops too #173

Open wdiechmann opened 2 months ago

wdiechmann commented 2 months ago

I may very well be barking up the wrong tree here - after giving up on IceCube (actually I've gone back and forth between the two of you, IceCube and Montrose, for a few days now, trying to get it to work), but here goes -

I'm on Rails 8.0.0.alpha, and Ruby 3.2.2, and Montrose 0.16., on a macbook Air macOS Sonoma 14.5 (the one with range anxiety; panic booting when you leave it alone), and I get this in my console:

mortimer(dev)> re
=> #<Montrose::Recurrence:e0024 {:every=>:week, :during=>[[[8, 0, 0], [14, 55, 0]]], :day=>[2, 3]}>
mortimer(dev)> tm
=> Tue, 09 Jul 2024 14:04:49 +0200
mortimer(dev)> tm2
=> Tue, 09 Jul 2024 15:04:49 +0200
mortimer(dev)> re.events.take 1
=> [Tue, 09 Jul 2024 12:37:32.000000000 UTC +00:00]
mortimer(dev)> re.include? tm
=> false
mortimer(dev)> re.include? tm2
^C(mortimer):48:in `<main>': abort then interrupt! (IRB::Abort)
mortimer(dev)> tm.class
=> DateTime
mortimer(dev)> tm2.class
=> DateTime

I would've expected re.include? tm to return true and re.include? tm2 to report false.

Any ideas, hints, caveats?

wdiechmann commented 2 months ago

On the issue of "when to display a event" in a calendar - how will I know where on a daily view to a calendar I should place an event, unless being able to somehow gather re.events.first.start_time or similar?

(1..23).each do |hr|
  (0..59).step(15) do |min|
    puts "%s %s" % [hr,min] if re.events.first - -- something here?
  end
end
rossta commented 2 months ago

Thanks for the report. It’s possible there is a bug but I haven’t had a chance to look into it. Can you show me how you created your recurrence and DateTime objects?

From your report, I can say that Montrose events are instances of Time, so asking for comparisons with DateTime may lead to unexpected results.

how will I know where on a daily view to a calendar I should place an event

I may not understand the question but you can always create a temporary recurrence from existing one for which the start time is from a given context, like your calendar view:

recurrence_1 = Montrose.r(:every=>:week, :during=>[[[8, 0, 0], [14, 55, 0]]], :day=>[2, 3]})

recurrence_2 = recurrence_1.starts(calendar_start_time) # different recurrence object
wdiechmann commented 2 months ago

ok - makes sense - and you seem to be at least partially right -

mortimer(dev)> r1 = Montrose.every :week
=> #<Montrose::Recurrence:225c4 {:every=>:week}>
mortimer(dev)> r2 = Montrose.on [:tuesday,:thursday]
=> #<Montrose::Recurrence:2f4a4 {:day=>[2, 4], :on=>[:tuesday, :thursday]}>
mortimer(dev)> r3 = Montrose.during "8:00-15:45"
=> #<Montrose::Recurrence:3929c {:during=>[[[8, 0, 0], [15, 45, 0]]]}>
mortimer(dev)> re = r1.merge(r2).merge(r3)
=> #<Montrose::Recurrence:42914 {:every=>:week, :during=>[[[8, 0, 0], [15, 45, 0]]], :day=>[2, 4], :on=>[:tuesday, :thursday]}>
mortimer(dev)> tm = Time.new 2024,7,9,8,0,5
=> 2024-07-09 08:00:05 +0200
mortimer(dev)> tm2 = Time.new 2024,7,9,15,46
=> 2024-07-09 15:46:00 +0200
mortimer(dev)> re.include? tm
=> true
mortimer(dev)> re.include? tm2
^C(mortimer):11:in `<main>': abort then interrupt! (IRB::Abort)

The abort is me being impatient -

My question regarding the "when to display an event in a calendar" must be a language thing - I mean almost every calendar exists only to present events - right? So, given I have a scedule like the one above - how would I place events on a day view - I mean: of the million+ downloads there must have been at least a few with that goal?

But I have not been able to find one single google hit mentioning how to evaluate schedules using Montrose when displaying a day calendar, like you know:

on monday, at 7 - should I present the schedule? no on monday at 7:15? No! 7:30? nah 7:45? nope 8:05? You bet'ya

What are people using Montrose for if not evaluating schedules/recurring events? What else is there really for Montrose to do? I mean, you have a bunch of schedules and you'd like to know if there is some sparetime you could R/R or go watch a game, or something, right?

But don't get me wrong - I really like the way you've (re)built the way to declare schedules - just not totally getting it (I mean I must be lost in the woods asking these silly kinds of questions)

sorry 😢

wdiechmann commented 1 month ago

how do I avoid hitting the 'loop' (see above) and still test whether a schedule is included?

when I test time inside a schedule - no problem - but when I try to test time outside a schedule, whether before or after, I hit the 'loop' (or whatever is really going on)

any ideas?

this is what I'm testing with:

mortimer(dev)> r1 = Montrose.every :week
=> #<Montrose::Recurrence:c5c38 {:every=>:week}>
mortimer(dev)> r2 = Montrose.on [:monday, :tuesday, :wednesday, :thursday, :friday]
=> #<Montrose::Recurrence:cb6c4 {:day=>[1, 2, 3, 4, 5], :on=>[:monday, :tuesday, :wednesday, :thursday, :friday]}>
mortimer(dev)> r3 = Montrose.during "08:00-16:00"
=> #<Montrose::Recurrence:d0278 {:during=>[[[8, 0, 0], [16, 0, 0]]]}>
mortimer(dev)> re = r1.merge(r2).merge(r3)
=> #<Montrose::Recurrence:d4314 {:every=>:week, :during=>[[[8, 0, 0], [16, 0, 0]]], :day=>[1, 2, 3, 4, 5], :on=>[:monday, :tuesday, :wednesday, :thursday, :friday]}>
mortimer(dev)> ws = Time.new 2024,7,8,7,5,0
=> 2024-07-08 07:05:00 +0200
mortimer(dev)> re.include? ws
^C(mortimer):30:in `<main>': abort then interrupt! (IRB::Abort)
mortimer(dev)>