ICAL在Outlook(Windows和Android)中的日期错误但在Google日历和Iphone中很好

时间:2017-06-08 07:12:15

标签: android outlook calendar google-calendar-api icalendar

嗨,我正忙着一个i cal日历。 但他显示错误的日期:

BEGIN:VEVENT
SUMMARY:TEST EVENT!
UID:140
STATUS:CONFIRMED
DTSTAMP;TZID=Europe/Amsterdam:20170610T220000Z
DTSTART;TZID=Europe/Amsterdam:20170610T220000Z
DTEND;TZID=Europe/Amsterdam:20170610T220000Z
LAST-MODIFIED:20170608T064314Z
LOCATION:STREET 1 1111 AA CITY
END:VEVENT
END:VCALENDAR

这可以是日期:11/06/2017 22:00(白天阿姆斯特丹) 在Outlook中的日期:11/06/2017 00:00(白天阿姆斯特丹)

这是我的其余代码:

BEGIN:VCALENDAR
METHOD:PUBLISH
VERSION:2.0
PRODID:-//2017/TEST CALENDAR//EN
BEGIN:VTIMEZONE
TZID:Europe/Amsterdam
BEGIN:STANDARD
DTSTART:20151025T020000
RDATE:20160327T030000
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:Europe/Amsterdam CET
END:STANDARD
BEGIN:STANDARD
DTSTART:20161030T020000
RDATE:20170326T030000
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:Europe/Amsterdam CET
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:20150601T073000
RDATE:20151025T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:Europe/Amsterdam CEST
END:DAYLIGHT
BEGIN:DAYLIGHT
DTSTART:20160327T030000
RDATE:20161030T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:Europe/Amsterdam CEST
END:DAYLIGHT

我希望有人可以帮助我! 非常感谢!

生成Ical的我的PHP代码如下:

<?php
date_default_timezone_set('Europe/Amsterdam');
$querystr ="
SELECT $wpdb->posts.* 
FROM $wpdb->posts, $wpdb->postmeta 
WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id 
AND ( $wpdb->posts.post_status = 'confirmed'
OR $wpdb->posts.post_status = 'pending'
)
ORDER BY $wpdb->posts.post_date DESC";
$pageposts = $wpdb->get_results($querystr, OBJECT);
?>
<?php
header("Content-Type: text/Calendar");
header("Content-Disposition: inline; filename=TESTAGENDA.ics");
// the iCal date format. Note the Z on the end indicates a UTC timestamp.
define('DATE_ICAL', 'Ymd\THis\Z');
// max line length is 75 chars. New line is \\n
$output = "BEGIN:VCALENDAR\r\n";
$output .= "METHOD:PUBLISH\r\n";
$output .= "VERSION:2.0\r\n";
$output .= "PRODID:-//2017/TEST AGENDA//EN\r\n";

$output .= "BEGIN:VTIMEZONE\r\n";
$output .= "TZID:Europe/Amsterdam\r\n";
$output .= "BEGIN:STANDARD\r\n";
$output .= "DTSTART:20151025T020000\r\n";
$output .= "RDATE:20160327T030000\r\n";
$output .= "TZOFFSETFROM:+0200\r\n";
$output .= "TZOFFSETTO:+0100\r\n";
$output .= "TZNAME:Europe/Amsterdam CET\r\n";
$output .= "END:STANDARD\r\n";
$output .= "BEGIN:STANDARD\r\n";
$output .= "DTSTART:20161030T020000\r\n";
$output .= "RDATE:20170326T030000\r\n";
$output .= "TZOFFSETFROM:+0200\r\n";
$output .= "TZOFFSETTO:+0100\r\n";
$output .= "TZNAME:Europe/Amsterdam CET\r\n";
$output .= "END:STANDARD\r\n";
$output .= "BEGIN:DAYLIGHT\r\n";
$output .= "DTSTART:20150601T073000\r\n";
$output .= "RDATE:20151025T020000\r\n";
$output .= "TZOFFSETFROM:+0100\r\n";
$output .= "TZOFFSETTO:+0200\r\n";
$output .= "TZNAME:Europe/Amsterdam CEST\r\n";
$output .= "END:DAYLIGHT\r\n";
$output .= "BEGIN:DAYLIGHT\r\n";
$output .= "DTSTART:20160327T030000\r\n";
$output .= "RDATE:20161030T020000\r\n";
$output .= "TZOFFSETFROM:+0100\r\n";
$output .= "TZOFFSETTO:+0200\r\n";
$output .= "TZNAME:Europe/Amsterdam CEST\r\n";
$output .= "END:DAYLIGHT\r\n";
$output .= "END:VTIMEZONE\r\n";
?>
<?php if ($pageposts){ ?>
<?php global $post; ?>
<?php foreach ($pageposts as $post): ?>
<?php $postmeta_reservering = get_post_meta( get_the_ID(), 'rtb', true );
if ( ! empty( $postmeta_reservering ) ) {
    $aantalpersonen = $postmeta_reservering['party'];
    $emailadres = $postmeta_reservering['email'];
    $telefoonnr = $postmeta_reservering['phone'];
    $ipadres = $postmeta_reservering['ip'];
}
?>
<?php setup_postdata($post); ?>
<?php if($post->post_status == 'confirmed'){$poststatus = 'CONFIRMED';}else{$poststatus = 'IN-PROCESS';}
$output .= "BEGIN:VEVENT\r\n";
$output .= "SUMMARY:".$post->post_title." Tel.:".$telefoonnr." (".$aantalpersonen." pers.)\r\n";
$output .= "UID:".$post->ID."\r\n";
$output .= "STATUS:".$poststatus."\r\n";
$output .= "DTSTAMP;TZID=Europe/Amsterdam:".date(DATE_ICAL, strtotime($post->post_date))."\r\n";
$output .= "DTSTART;TZID=Europe/Amsterdam:".date(DATE_ICAL, strtotime($post->post_date))."\r\n";
$output .= "DTEND;TZID=Europe/Amsterdam:".date(DATE_ICAL, strtotime($post->post_date))."\r\n";
$output .= "LAST-MODIFIED:".date(DATE_ICAL, strtotime($post->post_modified))."\r\n";
$output .= "LOCATION:STREET 01 1111 AA CITY\r\n";
$output .= "END:VEVENT\r\n";?>
<?php endforeach; ?>
<?php
// close calendar
$output .= "END:VCALENDAR";
// loop over events
echo $output;
?>
<?php }else{ ?>
    <span>No event!</span>
<?php } ?>

2 个答案:

答案 0 :(得分:2)

您正在使用带有时区的日期时间格式,但与此同时,您的后缀为Z,表示zulu / UTC时间。所以不同的客户会采用不同的解释。

只需从DTSTART和DTEND字段中删除最终的Z. DTSTAMP仅在祖鲁时间表示。最后,您的DTEND等于您的DTSTART,这是不合法的(必须及时,请参阅https://tools.ietf.org/html/rfc5545#section-3.8.2.2

DTSTAMP:20170610T220000Z
DTSTART;TZID=Europe/Amsterdam:20170610T220000
DTEND;TZID=Europe/Amsterdam:20170610T230000

答案 1 :(得分:0)

我也面临同样的问题,最后我用下面的方法解决了,希望这对你有帮助。

将您的日期传递给以下方法,以获得全球GMT时间

public static Date cvtToGMT(Date myDate){
    TimeZone timeZone = TimeZone.getDefault();
    Date cvtDate = new Date( myDate.getTime() - timeZone.getRawOffset());
    if(timeZone.inDaylightTime(cvtDate)){
        Date dstDate = new Date(cvtDate.getTime() - timeZone.getDSTSavings());
        if ( timeZone.inDaylightTime( dstDate )){
            cvtDate = dstDate;
        }
    }
    return cvtDate;
}