这个 ICS 文件有什么问题?

What's wrong with this ICS file?

我有一个问题,如果有人会这么好心。

实际上这是两个相互依存的问题。

我正在制作一个日历文件,我不习惯写文件,虽然将其写入.txt 文件似乎很简单。

  1. 我需要为 .ics 文件编写 headers 吗?如果需要,它是如何做到的?

  2. 这个在 iCal (MacOS) 中无法打开有什么问题?

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
CALSCALE:GREGORIAN
BEGIN:VEVENT
DTEND: 19700101T024640Z
UID: 5724dce4946da
DTSTAMP:20160430T162716Z
LOCATION:Green Park Station
DESCRIPTION:The Urban Playground Team are the original performance-parkour (2PK) company combining urban & contemporary dance with authentic French Free-Running. The Team have toured their performances and teaching across five continents for clients including the British Council. Since 2006 the team has included co-creator of Parkour Malik Diouf. In 2009 the Team designed and opened the UK’s first permanent parkour site\, and have since launched two more. In 2013 they founded the international performance-parkour network to support the development of 2PK globally.  They have appeared on BBC1’s Blue Peter and Sky1’s Got To Dance. <br />
Steam is a touring performance\, in which a group of urban explorers discover\, beneath canvas tarps\, the skeletal remains of a machine that changed the world. Inspired\, they shovel coal on the fires of the past. Engineers and drivers hurry to work at the sounds of a whistle’s blast\, and the passengers begin to dance. Inspired by classic movie genre Steam takes the UPG Team on a whistle stop tour through silent movies\, the Wild West\, James Bond\, WWI and the dark future of inner city commuting…<br />
Try out your own skills after the show - and you could even become part of the next performance!<br />
See also Weds June 1st.
URL;VALUE=URI:http://bathfringe.co.uk/single-event?u_name=Steam
SUMMARY:Steam
DTSTART:19700101T000000Z
END:VEVENT
END:VCALENDAR 

内容生成如下:

$contents = 

'BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
CALSCALE:GREGORIAN
BEGIN:VEVENT
DTEND: '.dateToCal($dateend) .'
UID: '. uniqid() .'
DTSTAMP:'. dateToCal(time()) .'
LOCATION:'. escapeString($address) .'
DESCRIPTION:'. escapeString($description) .'
URL;VALUE=URI:'. escapeString($uri) .'
SUMMARY:'. escapeString($summary) .'
DTSTART:'.dateToCal($datestart) .'
END:VEVENT
END:VCALENDAR '

$eol = "\r\n";

$contents = 

'BEGIN:VCALENDAR'.$eol.'
VERSION:2.0'.$eol.'
PRODID:-//hacksw/handcal//NONSGML v1.0//EN'.$eol.'
CALSCALE:GREGORIAN'.$eol.'
BEGIN:VEVENT'.$eol.'
DTEND: '.dateToCal($dateend) .$eol.'
UID: '. uniqid() .$eol.'
DTSTAMP:'. dateToCal(time()) .$eol.'
LOCATION:'. escapeString($address) .$eol.'
DESCRIPTION:'. escapeString($description) .$eol.'
URL;VALUE=URI:'. escapeString($uri) .$eol.'
SUMMARY:'. escapeString($summary) .$eol.'
DTSTART:'.dateToCal($datestart) .$eol.'
END:VEVENT'.$eol.'
END:VCALENDAR '.$eol;

主要是您需要在每次 link 中断后添加 $eol。

我看到两个问题:

第 1 期 - 额外的白色 spaces

您的 iCal 文件在非法位置包含几个白色 space:

DTEND: 19700101T024640Z
      ^

UID: 5724dce4946da
    ^

END:VCALENDAR 
             ^

嗯,从技术上讲,第二个可能不是无效的,因为 UID 被定义为具有 TEXT 值,但您应该准备好遇到麻烦。某些实现可能无法读取此内容,其他人可能会删除 space,其他人可能会包含它。

查看 RFC 5545 中的 ABNF 以获得正确的语法。一般来说,iCalendar 中没有可选的白色 space。

问题 2 - 转义不正确

DESCRIPTION 属性 包含几个新行序列,但未正确转义。内容行末尾的新行字符应转义为 \n(请参阅 RFC 5545, Section 3.3.11)。所以 DESCRIPTION 属性 应该是这样读的(全部在一行中,带有转义的换行符):

DESCRIPTION:The Urban Playground Team are the original performance-parkour (2PK) company combining urban & contemporary dance with authentic French Free-Running. The Team have toured their performances and teaching across five continents for clients including the British Council. Since 2006 the team has included co-creator of Parkour Malik Diouf. In 2009 the Team designed and opened the UK’s first permanent parkour site\, and have since launched two more. In 2013 they founded the international performance-parkour network to support the development of 2PK globally.  They have appeared on BBC1’s Blue Peter and Sky1’s Got To Dance. <br />\nSteam is a touring performance\, in which a group of urban explorers discover\, beneath canvas tarps\, the skeletal remains of a machine that changed the world. Inspired\, they shovel coal on the fires of the past. Engineers and drivers hurry to work at the sounds of a whistle’s blast\, and the passengers begin to dance. Inspired by classic movie genre Steam takes the UPG Team on a whistle stop tour through silent movies\, the Wild West\, James Bond\, WWI and the dark future of inner city commuting…<br />\nTry out your own skills after the show - and you could even become part of the next performance!<br />\nSee also Weds June 1st.

更好的是,像这样折叠线

DESCRIPTION:The Urban Playground Team are the original performance-park 
 our (2PK) company combining urban & contemporary dance with authentic 
 French Free-Running. The Team have toured their performances and teach
 ing across five continents for clients including the British Council. 
 Since 2006 the team has included co-creator of Parkour Malik Diouf. In
  2009 the Team designed and opened the UK’s first permanent parkour 
 site\, and have since launched two more. In 2013 they founded 
 the international performance-parkour network to support the development 
 of 2PK globally.  They have appeared on BBC1’s Blue Peter and Sky1’s 
 Got To Dance. <br />\nSteam is a touring performance\, in which a group 
 of urban explorers discover\, beneath canvas tarps\, the skeletal 
 remains of a machine that changed the world. Inspired\, they shovel coal 
 on the fires of the past. Engineers and drivers hurry to work at the 
 sounds of a whistle’s blast\, and the passengers begin to dance. 
 Inspired by classic movie genre Steam takes the UPG Team on a whistle 
 stop tour through silent movies\, the Wild West\, James Bond\, WWI and 
 the dark future of inner city commuting…<br />\nTry out your own 
 skills after the show - and you could even become part of the next 
 performance!<br />\nSee also Weds June 1st.

注意每行开头的前导白色 space。折叠在 Section 3.1 of RFC 5545.

中解释

另请注意,HTML 标签不受 iCalendar 支持。客户可能会也可能不会按照您的预期方式对此进行解释。有些客户只会在计划文本中显示 <br /> 标签。不过,没有 iCalendar 验证器应该抱怨这个。

关于 headers,iCalendar 的正确内容类型是 text/calendar,因此如果您 return 通过 HTTP 发送以下 header:

Content-type: text/calendar

如果您想将其发布为日历应用程序可以订阅的日历,您应该考虑向 VCALENDAR object 添加一个 METHOD:PUBLISH 字段,如 [=25] 中所述=].

最后:考虑使用现有的 iCalendar 库,它可以为您处理所有这些(转义、折叠......)。看看 Sabre-VObject.