TZInfo::AmbiguousTime invoking export_required_timezones, local_to_utc

105 views
Skip to first unread message

aiwilliams

unread,
Apr 4, 2011, 3:39:19 PM4/4/11
to RiCal, loren....@memberhub.com
Hello!

We are generating iCal files from a number of events, some of which
cause the production of timezone declarations that involve November 6,
2011. When I looked into the exception TZInfo::AmbiguousTime, it says
that this is raised when no disambiguation information is provided for
the local_to_utc invocation. Has anyone seen this and/or know what we
might be doing wrong? It seems at first that there is nothing we can
do, considering the stack trace [1]. I've included the code we are
using to produce the file [2].

If you need more information, please don't hesitate to ask! We'll dig
in however we should.

Adam Williams


1. Stack Trace
---------------------
[GEM_ROOT]/gems/activesupport-2.3.4/lib/active_support/vendor/
tzinfo-0.3.12/tzinfo/timezone.rb:363:in `period_for_local'
[GEM_ROOT]/gems/activesupport-2.3.4/lib/active_support/vendor/
tzinfo-0.3.12/tzinfo/timezone.rb:417:in `local_to_utc'
[GEM_ROOT]/gems/activesupport-2.3.4/lib/active_support/vendor/
tzinfo-0.3.12/tzinfo/time_or_datetime.rb:276:in `wrap'
[GEM_ROOT]/gems/activesupport-2.3.4/lib/active_support/vendor/
tzinfo-0.3.12/tzinfo/timezone.rb:413:in `local_to_utc'
[GEM_ROOT]/gems/ri_cal-0.8.7/lib/ri_cal/component/t_z_info_timezone.rb:
115:in `local_to_utc'
[GEM_ROOT]/gems/ri_cal-0.8.7/lib/ri_cal/component/t_z_info_timezone.rb:
129:in `export_local_to'
[GEM_ROOT]/gems/ri_cal-0.8.7/lib/ri_cal/required_timezones.rb:47:in
`export_to'
[GEM_ROOT]/gems/ri_cal-0.8.7/lib/ri_cal/required_timezones.rb:45:in
`each'
[GEM_ROOT]/gems/ri_cal-0.8.7/lib/ri_cal/required_timezones.rb:45:in
`export_to'
[GEM_ROOT]/gems/ri_cal-0.8.7/lib/ri_cal/component/calendar.rb:161:in
`export_required_timezones'
[GEM_ROOT]/gems/ri_cal-0.8.7/lib/ri_cal/component/calendar.rb:235:in
`export'
app/models/calendar/ics_calendar.rb:8:in `to_ical'

2. Our Code in to_ical
-------------------------------
RiCal.Calendar do |ical|
ical.add_x_property 'X-WR-CALNAME', @calendar.name
@calendar.events_since(31.days.ago).each do |e|
ical.event do |ievent|
ievent.uid "#{e.id}@#{Application.host}"
ievent.summary e.title
ievent.description e.notes if e.notes
ievent.dtstart e.all_day? ? e.starts_at.to_date :
e.starts_at
if e.ends_at
ievent.dtend e.all_day? ? e.ends_at.to_date + 1.day :
e.ends_at
end
ievent.location e.location if e.location
ievent.dtstamp Time.zone.now
end
end
end.export

Rick DeNatale

unread,
Apr 4, 2011, 5:23:38 PM4/4/11
to rica...@googlegroups.com
On Mon, Apr 4, 2011 at 3:39 PM, aiwilliams <ad...@thewilliams.ws> wrote:
> Hello!
>
> We are generating iCal files from a number of events, some of which
> cause the production of timezone declarations that involve November 6,
> 2011. When I looked into the exception TZInfo::AmbiguousTime, it says
> that this is raised when no disambiguation information is provided for
> the local_to_utc invocation.

I assume you know that ambiguous times occur when you use a local time
which re-occurs due to change from DST.

So on November 6, 2011 in the US we will 'fall back' at 2:00 am. So
the local time goes from

01:59:59 01:00:00 .. 01:59:59, 02:00:00

so all of the seconds between 01:00:00 and 01:59:59 occur twice and
have TWO different UTC values.

Not entirely sure, but I think you found an edge-case bug in ri_cal.

In order to export VTIMEZONE blocks from tzinfo data, ri_cal finds the
first and last time mentioned for each tzid in the calendar, it then
exports a VTIMEZONE which has the required DST transitions to cover
that range.

I think that the problem is that you have one of those first or last
times for a tzid falls in the ambiguous period. And that the fix
would be to patch ri_cal so that it uses something like the beginning
of the month (or maybe year) for the first time, and the end of the
month or year for the last time, which should safely move it out of
the danger zone and still provide coverage of the times in the
calendar. I'll have a look at this when I get a chance.

You might want to try these patches to lib/ri_cal/component/tz_info_timezone.rb

replace the method at line 113 with:

# convert time from utc time to this time zone
def utc_to_local(time)
@tzinfo_timezone.utc_to_local(time.to_ri_cal_ruby_value)
end

convert the method at line 128 with:

def export_local_to(export_stream, local_start, local_end) #:nodoc:
export_utc_to(export_stream,
local_to_utc(local_start.to_ri_cal_ruby_value, true),
local_to_utc(local_end.to_ri_cal_ruby_value, false))
end

I haven't actually tried this, but in theory it should pick the DST
equivalent UTC (which is earlier) for the earlier time in the range
and the ST equivalent for the end,

if that makes sense.

> --
> You received this message because you are subscribed to the Google Groups "RiCal" group.
> To post to this group, send email to rica...@googlegroups.com.
> To unsubscribe from this group, send email to rical_gem+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/rical_gem?hl=en.
>
>

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: http://github.com/rubyredrick
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

Reply all
Reply to author
Forward
0 new messages