Google日历/雅虎日历的iCal格式无效

时间:2015-10-19 20:33:09

标签: php calendar timezone

我已经从我的应用程序创建了日历文件(.ics)输出,以便在日历应用程序(如Google日历)中使用。我通过验证器运行了下面的文件,但似乎谷歌和雅虎日历都没想玩。我的本地Mac日历客户端100%工作。任何人都可以看到下面的文件明显有可能在Google日历中窒息吗?或者他们需要的任何其他字段?我也从雅虎日历中得到500错误。此时撕掉头发。

我尝试过有时区信息和没有时区信息,但似乎并没有太大的区别。

标头输出

        header('Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); 
        header('Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' ); 
        header('Cache-Control: no-store, no-cache, must-revalidate' );
        header('Cache-Control: post-check=0, pre-check=0', false );
        header('Pragma: no-cache' );
        header('Content-type: text/calendar;');
        header('Content-Disposition: inline; filename="calendar.ics"');
        header("Content-Description: File Transfer");
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: " . strlen($generated));

UTC时间或TZID我已经尝试过并且似乎没有什么区别。如果有人有一个非常简单的.ics事件的URL示例,它似乎可以工作"跨日历"很想看到它。或者,如果某人可以为此目的提供一些体面的库,并不是很难集成到CakePHP项目中,那就足够了。

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//MS//NONSGML//EN
X-WR-CALNAME:Holidays
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VEVENT
UID:1075
DTSTART;TZID=Europe/London:20150114T080000
DTEND;TZID=Europe/London:20150114T170000
DTSTAMP:20150114T080000Z
CREATED:20151019T211433Z
DESCRIPTION:Stat Holiday (1.0 days)
LAST-MODIFIED:20150114T080000Z
LOCATION:
SUMMARY: Statutory Day
SEQUENCE:0
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
UID:1076
DTSTART;TZID=Europe/London:20150116T080000
DTEND;TZID=Europe/London:20150116T170000
DTSTAMP:20150116T080000Z
CREATED:20151019T211433Z
DESCRIPTION:Stat Holiday (1.0 days)
LAST-MODIFIED:20150116T080000Z
LOCATION:
SUMMARY: Statutory Day
SEQUENCE:0
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
UID:1079
DTSTART;TZID=Europe/London:20151020T123000
DTEND;TZID=Europe/London:20151020T170000
DTSTAMP:20151020T123000Z
CREATED:20151019T211433Z
DESCRIPTION:Holiday Request (3.0 days) test
LAST-MODIFIED:20151020T123000Z
LOCATION:
SUMMARY:admin Leave
SEQUENCE:0
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
UID:1080
DTSTART;TZID=Europe/London:20151021T080000
DTEND;TZID=Europe/London:20151021T123000
DTSTAMP:20151021T080000Z
CREATED:20151019T211433Z
DESCRIPTION:Holiday (3.0 days) test
LAST-MODIFIED:20151021T080000Z
LOCATION:
SUMMARY:admin Leave
SEQUENCE:0
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
UID:1081
DTSTART;TZID=Europe/London:20151022T080000
DTEND;TZID=Europe/London:20151022T170000
DTSTAMP:20151022T080000Z
CREATED:20151019T211433Z
DESCRIPTION:Holiday Request (3.0 days) test
LAST-MODIFIED:20151022T080000Z
LOCATION:
SUMMARY:admin Leave
SEQUENCE:0
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
UID:1082
DTSTART;TZID=Europe/London:20151023T080000
DTEND;TZID=Europe/London:20151023T170000
DTSTAMP:20151023T080000Z
CREATED:20151019T211433Z
DESCRIPTION:Holiday Request (3.0 days) test
LAST-MODIFIED:20151023T080000Z
LOCATION:
SUMMARY:admin Leave
SEQUENCE:0
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

3 个答案:

答案 0 :(得分:4)

使用SO(Google Calendar errors on importing .ics file)的答案组合和https://gist.github.com/jakebellacera/635416的一些源代码

我在几个工具中测试的工作代码是:

<?php

//test
//
$summary = "test";
$datestart=time();
$dateend = $datestart + 3600;
$address = "Amsterdam";
$description = "testing ical format";
$filename = "test.ics";

// Variables used in this script:
//   $summary     - text title of the event
//   $datestart   - the starting date (in seconds since unix epoch)
//   $dateend     - the ending date (in seconds since unix epoch)
//   $address     - the event's address
//   $uri         - the URL of the event (add http://)
//   $description - text description of the event
//   $filename    - the name of this file for saving (e.g. my-event-name.ics)
//
// Notes:
//  - the UID should be unique to the event, so in this case I'm just using
//    uniqid to create a uid, but you could do whatever you'd like.
//
//  - iCal requires a date format of "yyyymmddThhiissZ". The "T" and "Z"
//    characters are not placeholders, just plain ol' characters. The "T"
//    character acts as a delimeter between the date (yyyymmdd) and the time
//    (hhiiss), and the "Z" states that the date is in UTC time. Note that if
//    you don't want to use UTC time, you must prepend your date-time values
//    with a TZID property. See RFC 5545 section 3.3.5
//
//  - The Content-Disposition: attachment; header tells the browser to save/open
//    the file. The filename param sets the name of the file, so you could set
//    it as "my-event-name.ics" or something similar.
//
//  - Read up on RFC 5545, the iCalendar specification. There is a lot of helpful
//    info in there, such as formatting rules. There are also many more options
//    to set, including alarms, invitees, busy status, etc.
//
//      https://www.ietf.org/rfc/rfc5545.txt
// 1. Set the correct headers for this file
header('Content-type: text/calendar; charset=utf-8');
header("Content-Disposition:inline;filename=".$filename);
// 2. Define helper functions
// Converts a unix timestamp to an ics-friendly format
// NOTE: "Z" means that this timestamp is a UTC timestamp. If you need
// to set a locale, remove the "\Z" and modify DTEND, DTSTAMP and DTSTART
// with TZID properties (see RFC 5545 section 3.3.5 for info)
//
// Also note that we are using "H" instead of "g" because iCalendar's Time format
// requires 24-hour time (see RFC 5545 section 3.3.12 for info).
function dateToCal($timestamp) {
  return date('Ymd\THis\Z', $timestamp);
}
// Escapes a string of characters
function escapeString($string) {
  return preg_replace('/([\,;])/','\\\$1', $string);
}
// 3. Echo out the ics file's contents
$iCal="BEGIN:VCALENDAR\r
VERSION:2.0\r
PRODID:-//hacksw/handcal//NONSGML v1.0//EN\r
CALSCALE:GREGORIAN\r
BEGIN:VEVENT\r
DTSTAMP:".dateToCal(time())."\r
DTSTART:".dateToCal($datestart)."\r
DTEND:".dateToCal($dateend)."\r
UID:".uniqid()."\r
LOCATION:".escapeString($address)."\r
DESCRIPTION:".escapeString($description)."\r
SUMMARY:".escapeString($summary)."\r
END:VEVENT\r
END:VCALENDAR";
file_put_contents($filename,$iCal);
print file_get_contents($filename);
unlink($filename);
exit;
?>

行结尾似乎很重要(所以\ r \ n)。

答案 1 :(得分:4)

您的文件是正确的,我已将其上传到谷歌日历中,因此它应该可以正常工作,但是如果您没有在文件回显后停止脚本,例如:

    //somewhere else in the script
    echo "this will break the file";
    header('Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); 
    header('Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' ); 
    header('Cache-Control: no-store, no-cache, must-revalidate' );
    header('Cache-Control: post-check=0, pre-check=0', false );
    header('Pragma: no-cache' );
    header('Content-type: text/calendar;');
    header('Content-Disposition: inline; filename="calendar.ics"');
    header("Content-Description: File Transfer");
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: " . strlen($generated));
    echo $generated;
    exit;//or return 200 or whatever
    echo "this could break the file except there is an exit;";//for example.

您实际上可能发送格式错误的文件。

答案 2 :(得分:0)

.ics文件中,我添加了一行

METHOD:REQUEST

和雅虎开始工作。 在我的情况下,我用.ics文件向hotmail,gmail和yahoo发送邮件,如果没有该行,yahoo就无法运行。 与

METHOD:PUBLISH

雅虎也不能工作