date - Perl Data::ICal print event time as T000000Z instead of omitting it -
i'm trying generate ical feed using data:ical events printed without time. i've read time not required if it's 000000 google calendar not handle events without time properly.
here example script , output. need output to in utc timezone.
#!/usr/bin/perl -w use strict; use date::ical; use data::ical; use data::ical::entry::event; use datetime; use data::dumper; sub get_utc_offset($) { ($orig_tz_str) = @_; # using set winter date avoid problems daylight savings time $utc_compare_datetime = datetime->new( year => 2012, month => 1, day => 1, hour => 1, minute => 1, time_zone => 'utc' ); $tz = datetime::timezone->new(name => $orig_tz_str); $utc_offset = $tz->offset_for_datetime($utc_compare_datetime); $utc_offset_str = datetime::timezone->offset_as_string($utc_offset); return $utc_offset_str; } sub add_ical_event($$$$$$) { ($calendar, $start, $end, $summary, $description, $timezone) = @_; $offset = get_utc_offset($timezone); $description = 'none' if (!$description); $event = data::ical::entry::event->new(); $event->add_properties( summary => $summary, description => $description, dtstart => date::ical->new( ical => $start, offset => $offset )->ical, dtend => date::ical->new( ical => $end, offset => $offset )->ical, dtstamp => date::ical->new( epoch => time )->ical ); $calendar->add_entry($event); } # tests # ---------------------------------------------------------------------------- $timezone = 'america/new_york'; $calendar = data::ical->new(); $calendar->add_properties( method => "publish", prodid => "-//test cal//nonsgml calendar//en", 'x-wr-calname' => 'test cal' ); (%events) = ( 1 => { summary => 'test shift tool - testing shift', description => '', start => '20130828t160000', end => '20130828t190000', timezone => $timezone }, 2 => { summary => 'new member meeting', description => '', start => '20130722t190000', end => '20130722t210000', timezone => $timezone }, 3 => { summary => 'public', description => '', start => '20130630t130000', end => '20130630t140000', timezone => $timezone } ); foreach $key (sort keys %events) { $e = $events{$key}; add_ical_event( $calendar, $e->{start}, $e->{end}, $e->{summary}, $e->{description}, $e->{timezone} ); } print $calendar->as_string;
notice events have start or end dates without time. when manually add t000000z, events imported google calendar. suggestions on how force events have time?
begin:vcalendar version:2.0 method:publish prodid:-//digital cheetah//nonsgml calendar//en x-wr-calname:digital cheetah begin:vevent description:none dtend:20130829z dtstamp:20130823t214317z dtstart:20130828t210000z summary:test shift tool - testing shift end:vevent begin:vevent description:none dtend:20130723t020000z dtstamp:20130823t214317z dtstart:20130723z summary:new member meeting end:vevent begin:vevent description:none dtend:20130630t190000z dtstamp:20130823t214317z dtstart:20130630t180000z summary:public end:vevent end:vcalendar
i've read time not required if it's 000000
that's not rfc says. let's refer following sections:
- 4.3.4 date
- 4.3.5 date-time
- 4.8.7.2 date/time
i'll quote relevant format specifications, here:
date = date-value date-value = date-fullyear date-month date-mday date-fullyear = 4digit date-time = date "t" time ;as specified in date , time ;value definitions dtstamp = "dtstamp" stmparam ":" date-time crlf
when output includes dtstamp, ical specification expects date-time
following it.
which brings date::ical , ical
method. return ical date
or date-time
? turns out, tries guess format want checking whether timestamp has time of 000000
. see @ line 286 of ical.pm.
it expect data::ical::entry handle scenario. missing validation code on end, @ moment i'm not seeing that's relevant. looks accepts property values without checking them.
depending on perspective, sounds bug or limitation of libraries.
so... how should fix this? ideally, 1 of these libraries should check , handle scenario. in meantime, though, need on feet:
quick , dirty fix: if time zero, bump 1 second; ical
return valid inaccurate date-time
string.
a little better: check return value ical
; if it's date
, reformat date-time
.
test before using it, maybe this:
dtstart => $ical =~ s/(\d{8})z/$1t000000z/r;
Comments
Post a Comment