在不同时区打开时无法让vCalendar(vcs)进行时间调整

时间:2017-04-14 16:36:37

标签: php vcalendar

我正在使用iCalcreator(v2.6)PHP库创建.vcs文件。在Outlook中打开事件(最新版本,我不了解其他版本)时,会议日期/时间不会调整为当地时间。我认为它可能与this有关,但设置X-MICROSOFT-CDO-TZID值似乎没有帮助。我希望有人知道有关vcs文件创建的事情,他们可以指出我正确的方向。这是我正在创建的vcs文件:

BEGIN:VCALENDAR
CALSCALE:GREGORIAN
METHOD:PUBLISH
PRODID:-//127.0.53.53//NONSGML iCalcreator 2.6//
VERSION:2.0
BEGIN:VTIMEZONE
TZID:US/Pacific
LAST-MODIFIED:20040110T032845Z
X-MICROSOFT-CDO-TZID:13
BEGIN:DAYLIGHT
DTSTART:19900404T010000
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU
TZNAME:PDT
END:DAYLIGHT
BEGIN:STANDARD
DTSTART:19901026T060000
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
TZNAME:PST
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
UID:20170413T205736CEST-5403Nbu2Iu@127.0.53.53
DTSTAMP:20170413T185736Z
DESCRIPTION:sdfg\n\nSome awesome description
DTSTART:20170419T180000
DURATION:PT3H0M0S
LOCATION:The best place in the world
SUMMARY:One fine summary
END:VEVENT
END:VCALENDAR

1 个答案:

答案 0 :(得分:0)

已经很晚了,但是这里有什么对我有用,也许这会帮助其他任何发生在这个问题上的人。

我从来没有尝试过TZOFFSETFROM ......所以不确定那是什么,或者它是否应该起作用。但是,如果您将时区放在DTSTART和DTEND中,它将自动调整。您只需要将日期设置为UTC,就像最后修改日期一样。我是这样做的($start$end是PHP DateTime对象):

"DTSTART:".$start->setTimezone(new DateTimeZone('UTC'))->format('Ymd\THis\Z').$eol.
"DTEND:".$end->setTimezone(new DateTimeZone('UTC'))->format('Ymd\THis\Z')

所以,基本上,所有这一切都是将日期放入UTC时区,然后在结尾处用Z格式化日期/时间,以便将其传达给客户。

一个完整的工作示例(如果它对任何人都有帮助)是:

<?php
    date_default_timezone_set('America/New_York');
    //CONFIGURE HERE
    $fromName           = "John Doe";
    $fromEmail          = "john.doe@example.com";
    $toName             = "Your Name";
    $toEmail            = 'yourname@example.com';
    $start              = new DateTime('2017-08-15 15:00');
    $end                = new DateTime('2017-08-15 16:00');
    $summary            = "Hello World Event";
    //END CONFIGURATION

    $uid                = "0123456789";
    $headers            = array();
    $boundary           = "_CAL_" . uniqid("B",true) . "_B_";
    $headers[]          = "MIME-Version: 1.0";
    $headers[]          = "Content-Type: multipart/alternative; boundary=\"".$boundary."\"";
    $headers[]          = "To: \"{$toName}\" <{$toEmail}>";
    $headers[]          = "From: \"{$fromName}\" <{$fromEmail}>";

    $calendarLines      = array(
        "BEGIN:VCALENDAR",
        "METHOD:REQUEST",
        "PRODID:-//PHP//MeetingRequest//EN",
        "VERSION:2.0",
        "BEGIN:VEVENT",
        "ORGANIZER;CN={$fromName}:MAILTO:{$fromEmail}",
        "ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN={$toName}:MAILTO:{$toEmail}",
        "DESCRIPTION:{$summary}",
        "SUMMARY:{$summary}",
        "DTSTART:".$start->setTimezone(new DateTimeZone('UTC'))->format('Ymd\THis\Z'),
        "DTEND:".$end->setTimezone(new DateTimeZone('UTC'))->format('Ymd\THis\Z'),
        "UID:{$uid}",
        "CLASS:PUBLIC",
        "PRIORITY:5",
        "DTSTAMP:".gmdate('Ymd\THis\Z'),
        "TRANSP:OPAQUE",
        "STATUS:CONFIRMED",
        "SEQUENCE:0",
        "LOCATION:123 Any Street",
        "BEGIN:VALARM",
        "ACTION:DISPLAY",
        "DESCRIPTION:REMINDER",
        "TRIGGER;RELATED=START:-PT15M",
        "END:VALARM",
        "END:VEVENT",
        "END:VCALENDAR"
    );


    $calendarBase64     = base64_encode(implode("\r\n",$calendarLines));
    //ensure we don't have lines longer than 70 characters for older computers:
    $calendarResult     = wordwrap($calendarBase64,68,"\n",true);

    $emailLines = array(
        "--{$boundary}",
        "Content-Type: text/html; charset=\"iso - 8859 - 1\"",
        "Content-Transfer-Encoding: quoted-printable",
        "",
        "<html><body>",
        "<h1>Hello World</h1>",
        "<p>This is a calendar event test</p>",
        "</body></html>",
        "",
        "--{$boundary}",
        "Content-Type: text/calendar; charset=\"utf - 8\"; method=REQUEST",
        "Content-Transfer-Encoding: base64",
        "",
        $calendarResult,
        "",
        "--{$boundary}--"
    );
    $emailContent   = implode("\n",$emailLines);

    $headersResult      = implode("\n",$headers);
    mail($toEmail, $summary, $emailContent, $headersResult );
    echo("<pre>".htmlentities($headersResult)."\n\n".htmlentities($emailContent)."</pre>");
    echo("<br /><br />");
    echo("<pre>".base64_decode($calendarResult)."</pre>");