I'm experiencing a problem where the events for one customer are
showing an hour behind their actual time. That is, the times are
correct in the application, but when the events are exported with
ri_cal and imported into iCal.app, the times of the events are an hour
earlier than they should be. All the other feeds I've tried are fine.
The problem can be resolved by changing two lines. In the DAYLIGHT
component of the single VTIMEZONE (America/New_York) of the document,
Times are behind an hour (exhibit A):
DTSTART:20090308T030000
RDATE:20090308T030000,20100314T030000
Times are correct (taken from a 'correct' feed, exhibit B):
DTSTART:20080309T030000
RDATE:20080309T030000,20090308T030000,20100314T030000
All the other properties are the same in the two documents.
I don't understand how the different DTSTART and extra RDATE make
things correct. Any insight would be greatly appreciated.
Adam Williams
DTEND;TZID=America/New_York;VALUE=DATE-TIME:20091029T094000
DTSTART;TZID=America/New_York;VALUE=DATE-TIME:20091029T092500
That event shows up as 9:25 AM, which is CORRECT.
> what's an example of a DTSTART from an event which is incorrect?
DTEND;TZID=America/New_York;VALUE=DATE-TIME:20091102T094000
DTSTART;TZID=America/New_York;VALUE=DATE-TIME:20091102T092500
That event shows up as 8:25 AM, which is INCORRECT.
Here is the complete definition of the VTIMEZONE:
BEGIN:VCALENDAR
PRODID;X-RICAL-TZSOURCE=TZINFO:-//com.denhaven2/NONSGML ri_cal gem//EN
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VTIMEZONE
TZID;X-RICAL-TZSOURCE=TZINFO:America/New_York
BEGIN:STANDARD
DTSTART:20081102T010000
RDATE:20081102T010000,20091101T010000
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:20090308T030000
RDATE:20090308T030000,20100314T030000
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
END:DAYLIGHT
END:VTIMEZONE
> Is it between 20080309T030000 and 20090308T030000 ?
Doesn't look like it.
> If so this would indicate a bug in figuring out which periods to
> export in the VTIMEZONE
Should I be looking for something wrong in our event data? Is it the
events that cause the additional information in the VTIMEZONE that
works:
DTSTART:20080309T030000
RDATE:20080309T030000,20090308T030000,20100314T030000
Based on my understanding of the RFC, I don't see how the older
DTSTART in that, or the additional RDATE of 20080309T030000, would
make any difference. iCal.app should be choosing the STANDARD
observance, shouldn't it? I suppose I don't really understand why it's
shifting the event's 20091102T092500 start time at all.
Thanks for such a great library, and your assistance in this, Rick.
Adam Williams
------------------------------------------------------------------------------------------------
--
Dwayne Purper
> I have a method for adding an rrule, where I just pass a hash to
> ical.add_rule.
>
> ------------------------------------------------------------------------------------------------
> def add_rrule
> remove_rrule
> rules = { :freq => frequency, :wkst => wkst }
> ical.add_rrule rules
> end
> ------------------------------------------------------------------------------------------------
>
> I'm not allowing my users to do anything complicated at this point,
> so I only keep one rrule at a time. (That's why the "remove_rrule"
> method is there.)
I believe you can simply use event.rrule=, with the value being the
hash, if you want to have only one rule.
> What I want to do is add a "BYDAY" line, to allow recurrences like
> "every Tuesday and Thursday."
I have in my hash:
hash[:byday] = ["2","4"]
> I see from the source that there's a RecurringDay class. How do I
> use that to set (and get) the BYDAY property in the RRULE?
When I read an imported document, I use this:
rules = event.rrule_property.first
rules.by_rule_list(:byday)
HTH,
Adam Williams
--
Dwayne Purper
It looks like Adam got you over the hump, but...
> I see from the source that there's a RecurringDay class. How do I use that
> to set (and get) the BYDAY property in the RRULE?
I highly recommend NOT mucking with or directly using any RiCal
classes which aren't subclasses of RiCal::Component
Classes like RecuringDay are used internally for enumerating
occurrences and are subject to change, and will almost certainly
confuse you if you try to understand them. I know that they do me.
<G>
--
Dwayne Purper
Okay,
I wrote the following spec. At first I thought I had a bug because I
had the expectations backward on what the offset should be for EDT vs
EST which made it look like the offsets were getting reversed, but
after trying in vain to 'debug' this realized that it should be -4
houts for EDT and -5 hours for EST not the other way around.
With that straightened out, all of the following passes without any
changes to RiCal itself. So I guess the net is that I can't seem to
reproduce your problem:
context "Adam's bug" do
before(:each) do
cal_string = <<ENDCAL
BEGIN:VCALENDAR
PRODID;X-RICAL-TZSOURCE=TZINFO:-//com.denhaven2/NONSGML ri_cal gem//EN
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VTIMEZONE
TZID;X-RICAL-TZSOURCE=TZINFO:America/New_York
BEGIN:STANDARD
DTSTART:20081102T010000
RDATE:20081102T010000,20091101T010000
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:20090308T030000
RDATE:20090308T030000,20100314T030000
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
DESCRIPTION:First Event
DTEND;TZID=America/New_York;VALUE=DATE-TIME:20091029T094000
DTSTART;TZID=America/New_York;VALUE=DATE-TIME:20091029T092500
END:VEVENT
BEGIN:VEVENT
DESCRIPTION:Second Event
DTEND;TZID=America/New_York;VALUE=DATE-TIME:20091102T094000
DTSTART;TZID=America/New_York;VALUE=DATE-TIME:20091102T092500
END:VEVENT
END:VCALENDAR
ENDCAL
@cal = RiCal.parse_string(cal_string).first
@event1 = @cal.events.find {|e| e.description == "First Event"}
# Event 1 starts on 10/29/2009 which is in EDT
@event2 = @cal.events.find {|e| e.description == "Second Event"}
# Event 2 starts on 11/02/2009 at 09:25 local which is in EST
end
context "the timezone" do
before(:each) do
@tz = @cal.timezones.first
end
context "period for local time 20091029T092500" do
before(:each) do
@period = @tz.period_for_local(DateTime.parse("20091029T092500"))
end
it "should be a daylight period " do
@period.should be_dst
end
it "should have a tzoffsetto of -0400" do
@period.tzoffsetto.should == "-0400"
end
end
context "period for local time 20091029T092500" do
before(:each) do
@period = @tz.period_for_local(DateTime.parse("20091102T0925"))
end
it "should be a standard period" do
@period.should_not be_dst
end
it "should have a tzoffsetto of -0500" do
@period.tzoffsetto.should == "-0500"
end
end
end
context "event 1 which starts in EDT" do
before(:each) do
@start = @event1.dtstart
end
it "should be on October 29" do
@start.mon.should == 10
@start.day.should == 29
end
it "should be at 9:25" do
@start.hour.should == 9
@start.min.should == 25
end
it "should have the right 'zone'" do
# Which one depends on whether ActiveSupport is included
["-04:00", "EDT"].should include(@start.zone)
end
it "should have the right tzid" do
@start.tzid.should == "America/New_York"
end
end
context "event 2 which starts in EST" do
before(:each) do
@start = @event2.dtstart
end
it "should be on November 2" do
@start.mon.should == 11
@start.day.should == 2
end
it "should be at 9:25" do
@start.hour.should == 9
@start.min.should == 25
end
it "should have a right 'zone'" do
["-05:00", "EST"].should include(@start.zone)
end
it "should have the right tzid" do
@start.tzid.should == "America/New_York"
end
end
end
Thanks a ton for the investigation. I apologize for the late reply.
The feed that was suffering the problem is working again. Here is a
diff of the STANDARD VTIMEZONE component, where the left side is the
old one, and the right side is the new:
< BEGIN:STANDARD
< DTSTART:20081102T010000
< RDATE:20081102T010000,20091101T010000
< TZOFFSETFROM:-0400
< TZOFFSETTO:-0500
< TZNAME:EST
< END:STANDARD
21a15,21
> BEGIN:STANDARD
> DTSTART:20091101T010000
> RDATE:20091101T010000
> TZOFFSETFROM:-0400
> TZOFFSETTO:-0500
> TZNAME:EST
> END:STANDARD
So, without any changes to code, something is causing it to behave
differently. At this point, I would suspect that is has something to
do with the events. We are only including events that occur two weeks
ago forward - there are events that would not be in the feed now
(DTSTAMP;TZID=America/New_York;VALUE=DATE-TIME:20091110T112903) that
were then (DTSTAMP;TZID=America/New_York;VALUE=DATE-TIME:
20091104T112256) - for that reason and simply because the user has
added more events. Do you think it would be worthwhile to analyze the
data of the events that would have been found 6 days ago that are not
found today?
Adam Williams
> Well the change to standard time was a week or two ago wasn't it.
It was indeed.
> If you want to look at the older data, and you find a problem could
> you please report it in the form of a failing spec or spec.
Yes, if I dig into it, I will.
> Since
> I've got a job now, I don't have as much time to reconstruct stuff
> from small data snippets and diffs.
Understood. Thanks again for your help.
Adam Williams