问题
I'm having a hard time getting my subscription calendar to work with Google Calendar. The following URL works correctly with Outlook and Apple Calendar (iCal), but I get an error from Google - "The address that you provided did not contain a calendar in a valid iCal or GData format."
My URL passes validation on the following validators (icalvalid.cloudapp.net/ and severinghaus.org/projects/icv/)
Can anyone provide any idea what is wrong? Here is the URL: https://beta.vcallboard.com/calls/exportcalendar.php?userID=Mg%3D%3D&token=MjB6N2E0OTk%3D
Theories I've already tried: - doesn't work over https - (I saved and uploaded the .ics file as a file in my server root and that URL worked - seems it has something to do with the auto-generation) - blank values for some fields aren't valid (it works if I upload it as a .ics file)
回答1:
You aren't defining the timezone that you are referencing in the ICS file. You have a number of lines as follows:
DTSTART;TZID=America/Chicago:20140121T010000
but to use these you need to define your timezone, for example:
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:Test calendar
X-WR-TIMEZONE:Indian/Reunion
BEGIN:VTIMEZONE
TZID:Indian/Reunion
TZURL:http://tzurl.org/zoneinfo/Indian/Reunion
X-LIC-LOCATION:Indian/Reunion
BEGIN:STANDARD
TZOFFSETFROM:+034152
TZOFFSETTO:+0400
TZNAME:RET
DTSTART:19110601T000000
RDATE:19110601T000000
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
...
A good place to obtain timezone definition files is tzurl.org
回答2:
I was baffled by my problem because I could manually import the .ics file that was output by my script and it was read by Google Calendar with no problem. So i figured I didn't have a problem with the actual format of the iCal file - I figured it had to be a problem with the headers or some server config. So I did a few experiments...
Long story short, I was able to get this to work on Google Calendar by doing the following:
Load up a variable with all the iCal data, pulling from the database, site constants etc. Make sure to use
\r
and\n
for better validation in the validators.$iCal = "BEGIN:VCALENDAR\r VERSION:2.0\r PRODID:-//VirtualCallboard//".SITENAME."//EN\r CALSCALE:GREGORIAN\r METHOD:PUBLISH\r"; while ($r=mysql_fetch_assoc($result)) { // i do a bunch of stuff here to get variables ready for the output $iCal .= "BEGIN:VEVENT\r DTSTAMP:".gmdate("Ymd\THis\Z")."\r DTSTART:".date("Ymd\THis\Z", strtotime($r[tdstart]))."\r DTEND:'.date("Ymd\THis\Z", strtotime($r[tdend]))."\r SUMMARY:$r[title]\r UID:$r[callid]@".$_SERVER['HTTP_HOST']."\r DESCRIPTION:$r[notes].\r LOCATION:$r[location_name].\r STATUS:CONFIRMED\r END:VEVENT\r\n"; } $iCal .= "END:VCALENDAR";
Escape the special characters (all I know right now are commas). And then (here's the secret) - use file_put_contents to write the string in the iCal variable into a file with a .ics extension in a cache directory.
//escape special characters. $iCal = str_replace(",","\,",$iCal); //output to a file $filename = 'site/cache/'.date("YmdHis").'.ics'; file_put_contents($filename,$iCal);
Call the headers:
//set correct content-type-header header("Content-Type:text/calendar"); header("Content-Disposition:inline;filename=my_ical.ics");
Use file_get_contents to read the .ics data back out of the file and output it to the browser.
print file_get_contents($filename);
cleanup the .ics file I created in my cache directory.
unlink($filename); exit;
For some reason, which I can't explain, this made the exact same file work in Google Calendar. So this is compatible with Outlook, Google Calendar, and Apple Calendar.
来源:https://stackoverflow.com/questions/21275581/google-calendar-errors-on-importing-ics-file