I just ran into this loading (with the latest vpim gem, 0.597) the calendar from http://homepage.mac.com/ical/.calendars/US32Holidays.ics (a standard US holidays calendar provided by Apple). The following script shows the problem I''m having: #!/usr/bin/env ruby require ''rubygems'' require ''vpim'' Event = Vpim::Icalendar::Vevent leap = Event.create_yearly(Time.mktime(2004, 2, 29), ''Leap day'') leap.occurences.each(Time.mktime(2009, 3, 4)) { |time| puts time.to_s } Not only is it showing up for years that aren''t leap years, it gets pushed to March 1 on the first non-leap year and stays there even on leap years. Incidentally, why isn''t the tracker active for the vpim project? I would have submitted this as a bug otherwise. --Greg
Quoting gsslist+vpim at anthropohedron.net, on Sun, Mar 02, 2008 at 09:21:21PM -0500:> leap = Event.create_yearly(Time.mktime(2004, 2, 29), ''Leap day'') > > leap.occurences.each(Time.mktime(2009, 3, 4)) { |time| > puts time.to_s > } > > Not only is it showing up for years that aren''t leap years, it gets pushed > to March 1 on the first non-leap year and stays there even on leap years.Sorry about that. vPim uses ruby''s Date class. Add a year to 2004-02-29, and you get: irb(main):011:0> Time.mktime(2005, 2, 29) => Tue Mar 01 00:00:00 -0800 2005 Here''s another example from my notes: " - bug: deal with "round down" that Date does when you add a month, and the dofmonth is not " in valid range -> if you have jan31 repeating monthly with iCal, you shouldn''t get an " occurence in Feb " " ensemble:~/p/ruby/vpim % ./rrule.rb --start ''20050131T000000Z'' ''FREQ=MONTHLY'' | head " Start: Mon Jan 31 00:00:00 EST 2005 " Rrule: FREQ=MONTHLY " count= 0 Mon Jan 31 00:00:00 EST 2005 " count= 1 Mon Feb 28 00:00:00 EST 2005 " count= 2 Mon Mar 28 00:00:00 EST 2005 " count= 3 Thu Apr 28 00:00:00 EDT 2005 " count= 4 Sat May 28 00:00:00 EDT 2005 " count= 5 Tue Jun 28 00:00:00 EDT 2005 " count= 6 Thu Jul 28 00:00:00 EDT 2005 " count= 7 Sun Aug 28 00:00:00 EDT 2005 " " I need to keep my own date/time, and not use Time as the basic object in my iteration. " " Then, I can eliminate non-existent times before yielding them. I''ll see what this involves, maybe I can correct for some of Date''s problems without reimplementing it, which I don''t have the time for, though I might have to do it for timezone support.> Incidentally, why isn''t the tracker active for the vpim project? I would > have submitted this as a bug otherwise.Would you have preferred to submit with a tracker? I could turn it on, I just thought people would rather email me if they had a comment, or subscribe to the list. My direct email address is part of the docs. Cheers, Sam
Gregory Seidman wrote:> I just ran into this loading (with the latest vpim gem, 0.597) the calendar > from http://homepage.mac.com/ical/.calendars/US32Holidays.ics (a standard > US holidays calendar provided by Apple).I don''t see leap day in that ics file in the file I just retrieved, dated Nov 3, 2006. I don''t think that Leap day is a standard US holiday.> The following script shows the > problem I''m having: > > #!/usr/bin/env ruby > > require ''rubygems'' > require ''vpim'' > > Event = Vpim::Icalendar::Vevent > > leap = Event.create_yearly(Time.mktime(2004, 2, 29), ''Leap day'') > > leap.occurences.each(Time.mktime(2009, 3, 4)) { |time| > puts time.to_s > } > > Not only is it showing up for years that aren''t leap years, it gets pushed > to March 1 on the first non-leap year and stays there even on leap years. >You are creating a yearly event. According to the rdoc, create_yearly "creates a yearly repeating event, such as for a birthday." If your birthday was leap day, there might be various awkwardnesses, but you would get a year older every year. I believe that most business rules for handling leap day treat leap day as March 1st. For instance, if you opened a yearly subscription on leap day this year, it will renew on March 1 next year. Your subscription would continue to renew on March 1, even in leap years. I think that if you are going to create a Leap Day holiday, you are going to have to do it with recurrence rules, but I''m not sure why you would be doing that, so perhaps I don''t understand your situation. Which brings me back to the ics file from Apple. -- Ray
On Sun, Mar 02, 2008 at 11:09:12PM -0800, Ray Baxter wrote:> Gregory Seidman wrote: > > I just ran into this loading (with the latest vpim gem, 0.597) the calendar > > from http://homepage.mac.com/ical/.calendars/US32Holidays.ics (a standard > > US holidays calendar provided by Apple). > > I don''t see leap day in that ics file in the file I just retrieved, > dated Nov 3, 2006. I don''t think that Leap day is a standard US holiday.[...] Whoops! You are correct. I thought it was in that file and it turned out to be in one of my own. It is a yearly recurring event on Feb. 29, and it is correctly displayed in at least two other calendaring programs (Apple''s ical and Mozilla Sunbird/Lightning).> > Not only is it showing up for years that aren''t leap years, it gets pushed > > to March 1 on the first non-leap year and stays there even on leap years. > > You are creating a yearly event. According to the rdoc, create_yearly > "creates a yearly repeating event, such as for a birthday." If your > birthday was leap day, there might be various awkwardnesses, but you > would get a year older every year. I believe that most business rules > for handling leap day treat leap day as March 1st. For instance, if you > opened a yearly subscription on leap day this year, it will renew on > March 1 next year. Your subscription would continue to renew on March 1, > even in leap years. > > I think that if you are going to create a Leap Day holiday, you are > going to have to do it with recurrence rules, but I''m not sure why you > would be doing that, so perhaps I don''t understand your situation. Which > brings me back to the ics file from Apple.You are talking about business needs, which has nothing to do with what one means by "every February 29". Suppose you plan a party for every leap day, and want to be reminded a week ahead of time. You only want to be reminded on years when leap day occurs. No one needs to be reminded to be a year older.> Ray--Greg
On Sun, Mar 02, 2008 at 10:56:44PM -0800, Sam Roberts wrote:> Quoting gsslist+vpim at anthropohedron.net, on Sun, Mar 02, 2008 at 09:21:21PM -0500: > > leap = Event.create_yearly(Time.mktime(2004, 2, 29), ''Leap day'') > > > > leap.occurences.each(Time.mktime(2009, 3, 4)) { |time| > > puts time.to_s > > } > > > > Not only is it showing up for years that aren''t leap years, it gets > > pushed to March 1 on the first non-leap year and stays there even on > > leap years. > > Sorry about that. vPim uses ruby''s Date class. Add a year to 2004-02-29, > and you get: > > irb(main):011:0> Time.mktime(2005, 2, 29) > => Tue Mar 01 00:00:00 -0800 2005 > > Here''s another example from my notes: > > " - bug: deal with "round down" that Date does when you add a month, and the dofmonth is not > " in valid range -> if you have jan31 repeating monthly with iCal, you shouldn''t get an > " occurence in Feb[...]> " I need to keep my own date/time, and not use Time as the basic object in my iteration. > " > " Then, I can eliminate non-existent times before yielding them. > > I''ll see what this involves, maybe I can correct for some of Date''s > problems without reimplementing it, which I don''t have the time for, > though I might have to do it for timezone support.I think you should be able to do it with a quick check on mday. If calculated_time.mday != original_time.mday then skip it and move on. You''ll need to keep a separate iteration variable from the time itself, so instead of adding a month or a year to a Time you are adding i*(month or year) to the dtstart. I haven''t dug into the code to see if it''s an easy fix. If I''d noticed the issue earlier in the weekend, I would have had time. Alas... BTW, this is coming up in the context of my (new this weekend, but already up and working) CalTerm project (find it on rubyforge).> > Incidentally, why isn''t the tracker active for the vpim project? I would > > have submitted this as a bug otherwise. > > Would you have preferred to submit with a tracker? I could turn it on, I > just thought people would rather email me if they had a comment, or > subscribe to the list. My direct email address is part of the docs.I like submitting to a tracker in large part because I can check if it''s come up before and, if so, simply comment on the previous bug. If it hasn''t come up before, I can submit it. Either way, any discussion on it (and patches, if any) stay associated with the issue.> Cheers, > Sam--Greg
---------- Forwarded message ---------- From: Sam Roberts <vieuxtech at gmail.com> Date: Mon, Mar 3, 2008 at 10:23 AM Subject: Re: [Vpim-talk] Leap day bug To: Ray Baxter <ray.baxter at mindspring.com> On Sun, Mar 2, 2008 at 11:09 PM, Ray Baxter <ray.baxter at mindspring.com> wrote: > > Not only is it showing up for years that aren''t leap years, it gets pushed > > to March 1 on the first non-leap year and stays there even on leap years. > > > > You are creating a yearly event. According to the rdoc, create_yearly > "creates a yearly repeating event, such as for a birthday." If your > birthday was leap day, there might be various awkwardnesses, but you > would get a year older every year. I believe that most business rules > for handling leap day treat leap day as March 1st. For instance, if you > opened a yearly subscription on leap day this year, it will renew on > March 1 next year. Your subscription would continue to renew on March 1, > even in leap years. That explains why ruby''s Date class behaviour isn''t considered a bug. Unfortunately for vPim, the RFC is clear on this. A monthly event occurring on the 31 should occur only on those months that have a 31. If someone wanted the last day of each month -1 can be used for the day. Sam
On Mon, Mar 03, 2008 at 10:32:46AM -0800, Sam Roberts wrote:> On Mon, Mar 3, 2008 at 7:06 AM, Gregory Seidman > <gsslist+vpim at anthropohedron.net> wrote: > > I think you should be able to do it with a quick check on mday. If > > calculated_time.mday != original_time.mday then skip it and move on. > > You''ll need to keep a separate iteration variable from the time > > itself, so instead of adding a month or a year to a Time you are > > adding i*(month or year) to the dtstart. > > There are other areas this shows up, it might not be so simple, or > perhaps it will.Do you know offhand where it comes up other than occurences iteration? On a separate note, occurences should be occurrences (i.e. it''s misspelled). Changing it would be bad for backward compatibility, but maybe an alias?> > BTW, this is coming up in the context of my (new this weekend, but > > already up and working) CalTerm project (find it on rubyforge). > > Looks fun. I''d like to have CalDAV support in vPim, so if you do some > work on that consider contributing it to the project. Even if its > simple support, its better than nothing. Also, gcalendar integration > might be nice to have outside of the context of CalTerm, so feel free > to contribute that, too!I don''t know when I''ll get to it (I had a miraculously free weekend which is how I hammered out what I have so far), but I expect it will make more sense to work that stuff into vpim than outside of it anyway. I''ll definitely contribute my work. When I start implementing writing it will be first to the filesystem, then via WebDAV, and then I''ll start looking into CalDAV and (maybe) GData. All my calendars are currently hosted on one WebDAV server or another, so I don''t have much of an itch to scratch for either GData or CalDAV right now.> Thanks, > Sam--Greg