Solved

php xml parse Google calendar events - end time

Posted on 2012-03-25
19
1,278 Views
Last Modified: 2014-11-12
i am using
http://www.ibm.com/developerworks/opensource/library/os-php-xpath/
listing number 5
i have it working well
im trying to get the end times now and im having problems its showing dec 69 dates for end time i guess its not reading the value correctly

my current code
<!-- Start up the PHP script -->

<?php
// Modified from P.J. Cabreras "Listing 5" at
// http://www.ibm.com/developerworks/opensource/library/os-php-xpath/
// License at http://www.ibm.com/developerworks/apps/download/index.jsp?contentid=270615&filename=os-php-xpath.google-calendar-api.zip&method=http&locale=worldwide:w

//  Set the time zone.  See the supported time zones here:
//   http://php.net/manual/en/timezones.php
//  As an example, we'll use US Eastern time, so

    date_default_timezone_set('America/New_York');

//  This tells the code where to look in Googles data protocal
//   to find the tags used in the calendar feed.  Note that
//   we're only looking at "confirmed" links.  For more details, see
//   http://code.google.com/apis/gdata/docs/1.0/elements.html

    $confirmed = 'http://schemas.google.com/g/2005#event.confirmed';

// This puts the date in a form Google will read:

    $right_now = date("Y-m-d\Th:i:sP", time());

//  For our purposes, a week will be 8 days.  This allows next
//   Sundays schedule to appear on the preceeding Sunday
//  Adjust for your own purposes

    $week_in_seconds = 60 * 60 * 24 * 8;
    $next_week = date("Y-m-d\Th:i:sP", time() + $week_in_seconds);

//  This is my version of the call to Googles API.  See
//   http://code.google.com/apis/calendar/data/2.0/reference.html#Parameters
//   for alternatives.

//   This version gets all the events happening starting from right now until
//   eight days from now.

//  Dont forget to replace "yourcalendaraddress" by your Google
//   calendar address.  For your default calendar, its just your gmail
//   address before the "@gmail.com"

    $feed = "http://www.google.com/calendar/feeds/lcwchurch%40gmail.com/" .
        "public/full?orderby=starttime&singleevents=true&" .
        "sortorder=ascending&" .
        "start-min=" . $right_now . "&" .
        "start-max=" . $next_week;
//http://www.google.com/calendar/feeds/lcwchurch%40gmail.com/public/full?orderby=starttime&singleevents=true&sortorder=ascending&start-min=2012-03-25T01:59:41-04:00&start-max=2012-04-02T01:59:41-04:00
//echo  $feed."<br>";

//  Create a new document from the feed

    $doc = new DOMDocument();
    $doc->load( $feed );

//  We're looking for all the entries in the feed, denoted, logically
//   enough, by the tag "entry"

    $entries = $doc->getElementsByTagName( "entry" );

//  This is pretty much self-explanatory

    foreach ( $entries as $entry ) {

// Find the status of a given entry

        $status = $entry->getElementsByTagName( "eventStatus" );
        $eventStatus = $status->item(0)->getAttributeNode("value")->value;

// If it's confirmed, parse it

        if ($eventStatus == $confirmed) {

// This looks at the "title" tag.

            $titles = $entry->getElementsByTagName( "title" );
            $title = $titles->item(0)->nodeValue;

// $title might have an unescaped isolated ampersand in it (as in
// "Chat & Chew".)  This will fix that so that the web page will validate

           // $title = ereg_replace(" & ", " &amp; ", $title);

// This looks at the "gd:when" tag,
//  to get the actual time the event is going to happen.
// Note that the "gd" indicates this is part of the Google schema

            $times = $entry->getElementsByTagName( "when" );

// Pull off the time

            $startTime = $times->item(0)->getAttributeNode("startTime")->value;
            $when_start = date( "g:i a", strtotime( $startTime ) );
            $endTime = $times->item(0)->getAttributeNode("endTime")->value;
            $when_end = date( "g:i a", strtotime( $endTime ) );

// Parse it into something we like.  For other formatting options see
// http://php.net/manual/en/function.date.php

	    //$when = date( "l\, F j\, Y \a\\t h:i A T", strtotime( $startTime ) );
	    $when = date( "l jS \of F", strtotime( $startTime ) );
	    

// Ditto for location

            $places = $entry->getElementsByTagName( "where" );
            $where = $places->item(0)->getAttributeNode("valueString")->value;

// There may be multiple link elements in the file.  This picks off
//  the first one, which takes you to the event page for the Google
//  calendar.  Note that "link", like "title", is not part of the
//  Google schema, so it's referenced by "<link ...>" rather than
//  "<gd:link ...>"

            $web = $entry->getElementsByTagName( "link" );
            $link = $web->item(0)->getAttributeNode("href")->value;

//  You can pick off other tags, of course, but these are the ones
//   I need.

//  Now print out the HTML for this element.  Be careful to
//   escape all of the double quotation marks.  Note that
//   you don't really need the "\n" end of line characters,
//   I just put them in to make the resulting page easier to read
//   for debugging purposes

            //echo "<strong></strong> ";
// If you don't specify the time zone here, (leaving off &amp;...New_York),
//  Then anyone actually clicking on the link will get the time of the event
//  in GMT.  So change America/New_York to your default time zone
//  (added 2 October 2010):
            if (date( "l jS \of F", strtotime('today')) == $when) 
	    {
	    echo "<SPAN style='color:#800000'><STRONG>$when</STRONG></SPAN> <br />\n";
	    }
	    else 
	    {
	    echo "<STRONG>$when</STRONG> <br />\n";
	    }
	    
            
            echo $when_start." till ".$when_end." - <a target=\"_blank\" href=\"$link&amp;ctz=America/New_York\">$title</a> <br />\n";
            //echo "$where<br />\n";
            echo "\n";
	}
}
?>

<!-- That's the end of the PHP code, close up the list and end the page -->

Open in new window


what im really trying to do is make the end time show and turn the current event going on right now to green, and the rest of the days to maroon (have that part all ready)

thanks in advance for any code or help you may provide
Johnny
0
Comment
Question by:Johnny
  • 12
  • 7
19 Comments
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
The "December 1969" issue usually means that the date was formatted from a Unix timestamp value of zero, which is the same as FALSE, which is what you get when you run strtotime() and it cannot interpret the DATETIME string.  This article will show you a little more about how to handle DATETIME values in PHP and MySQL.  Read it over while I look at the code you posted here.  I'll see if I can spot anything obvious.
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_201-Handling-date-and-time-in-PHP-and-MySQL.html
0
 

Author Comment

by:Johnny
Comment Utility
i got a little farther

current code
<!-- Start up the PHP script -->

<?php
// Modified from P.J. Cabreras "Listing 5" at
// http://www.ibm.com/developerworks/opensource/library/os-php-xpath/
// License at http://www.ibm.com/developerworks/apps/download/index.jsp?contentid=270615&filename=os-php-xpath.google-calendar-api.zip&method=http&locale=worldwide:w

//  Set the time zone.  See the supported time zones here:
//   http://php.net/manual/en/timezones.php
//  As an example, we'll use US Eastern time, so

    date_default_timezone_set('America/New_York');

//  This tells the code where to look in Googles data protocal
//   to find the tags used in the calendar feed.  Note that
//   we're only looking at "confirmed" links.  For more details, see
//   http://code.google.com/apis/gdata/docs/1.0/elements.html

    $confirmed = 'http://schemas.google.com/g/2005#event.confirmed';

// This puts the date in a form Google will read:

    $right_now = date("Y-m-d\Th:i:sP", time());

//  For our purposes, a week will be 8 days.  This allows next
//   Sundays schedule to appear on the preceeding Sunday
//  Adjust for your own purposes

    $week_in_seconds = 60 * 60 * 24 * 8;
    $next_week = date("Y-m-d\Th:i:sP", time() + $week_in_seconds);

//  This is my version of the call to Googles API.  See
//   http://code.google.com/apis/calendar/data/2.0/reference.html#Parameters
//   for alternatives.

//   This version gets all the events happening starting from right now until
//   eight days from now.

//  Dont forget to replace "yourcalendaraddress" by your Google
//   calendar address.  For your default calendar, its just your gmail
//   address before the "@gmail.com"

    $feed = "http://www.google.com/calendar/feeds/lcwchurch%40gmail.com/" .
        "public/full?orderby=starttime&singleevents=true&" .
        "sortorder=ascending&" .
        "start-min=" . $right_now . "&" .
        "start-max=" . $next_week;
//http://www.google.com/calendar/feeds/lcwchurch%40gmail.com/public/full?orderby=starttime&singleevents=true&sortorder=ascending&start-min=2012-03-25T01:59:41-04:00&start-max=2012-04-02T01:59:41-04:00
//echo  $feed."<br>";

//  Create a new document from the feed

    $doc = new DOMDocument();
    $doc->load( $feed );

//  We're looking for all the entries in the feed, denoted, logically
//   enough, by the tag "entry"

    $entries = $doc->getElementsByTagName( "entry" );

//  This is pretty much self-explanatory

    foreach ( $entries as $entry ) {

// Find the status of a given entry

        $status = $entry->getElementsByTagName( "eventStatus" );
        $eventStatus = $status->item(0)->getAttributeNode("value")->value;

// If it's confirmed, parse it

        if ($eventStatus == $confirmed) {

// This looks at the "title" tag.

            $titles = $entry->getElementsByTagName( "title" );
            $title = $titles->item(0)->nodeValue;

// $title might have an unescaped isolated ampersand in it (as in
// "Chat & Chew".)  This will fix that so that the web page will validate

           // $title = ereg_replace(" & ", " &amp; ", $title);

// This looks at the "gd:when" tag,
//  to get the actual time the event is going to happen.
// Note that the "gd" indicates this is part of the Google schema

            $times = $entry->getElementsByTagName( "when" );
            // There's actually something in the list
	    /*
	    $result=$times;
	    foreach($result as $node) {
	      echo "result * {$node->nodeName} - {$node->nodeValue} *";
	    }
	    */

// Pull off the time

            $startTime = $times->item(0)->getAttributeNode("startTime")->value;
            $when_start = date( "g:i a", strtotime( $startTime ) );
            $endTime = $times->item(1)->getAttributeNode("endTime")->value;
            $when_end = date( "g:i a", strtotime( $endTime ) );

// Parse it into something we like.  For other formatting options see
// http://php.net/manual/en/function.date.php

	    //$when = date( "l\, F j\, Y \a\\t h:i A T", strtotime( $startTime ) );
	    $when = date( "l jS \of F", strtotime( $startTime ) );
	    

// Ditto for location

            $places = $entry->getElementsByTagName( "where" );
            $where = $places->item(0)->getAttributeNode("valueString")->value;

// There may be multiple link elements in the file.  This picks off
//  the first one, which takes you to the event page for the Google
//  calendar.  Note that "link", like "title", is not part of the
//  Google schema, so it's referenced by "<link ...>" rather than
//  "<gd:link ...>"

            $web = $entry->getElementsByTagName( "link" );
            $link = $web->item(0)->getAttributeNode("href")->value;

//  You can pick off other tags, of course, but these are the ones
//   I need.

//  Now print out the HTML for this element.  Be careful to
//   escape all of the double quotation marks.  Note that
//   you don't really need the "\n" end of line characters,
//   I just put them in to make the resulting page easier to read
//   for debugging purposes

            //echo "<strong></strong> ";
// If you don't specify the time zone here, (leaving off &amp;...New_York),
//  Then anyone actually clicking on the link will get the time of the event
//  in GMT.  So change America/New_York to your default time zone
//  (added 2 October 2010):
            if (date( "l jS \of F", strtotime('today')) == $when) 
	    {
	    echo "<SPAN style='color:#800000'><STRONG>$when</STRONG></SPAN> <br />\n";
	    }
	    else 
	    {
	    echo "<STRONG>$when</STRONG> <br />\n";
	    }
	    
            
            echo $when_start." till ".$when_end." - <a target=\"_blank\" href=\"$link&amp;ctz=America/New_York\">$title</a> <br />\n";
            //echo $when_start." - <a target=\"_blank\" href=\"$link&amp;ctz=America/New_York\">$title</a> <br />\n";
            //echo "$where<br />\n";
            echo "\n";
	}
}
?>

<!-- That's the end of the PHP code, close up the list and end the page -->

Open in new window


i was playing a bit and still reading up on xml parseing this is fairly new to me so i dont get it yet.
but i was trying to see the values of "when" and i cant display then i tried in the code, but that didnt work well either.
i changed the value of 0 to 1 in the endtime thinking that it has more then one value, and i got some output(correctly too)
but i have an error of

Sunday 25th of March
8:00 am till 9:00 am - Worship Service
Sunday 25th of March
9:30 am till 10:30 am - Sunday School & Bible Study
Sunday 25th of March
11:00 am till 12:00 pm - Worship Service
Monday 26th of March
7:00 pm till 8:00 pm - Bible Study @ Bains
Monday 26th of March
7:00 pm till 8:00 pm - Core Beliefs

Fatal error: Call to a member function getAttributeNode() on a non-object in /home/content/97/8973997/html/google_calendar_xml_parse_to_html.php on line 127

line 127 is:
$endTime = $times->item(1)->getAttributeNode("endTime")->value;

so maybe the item value is not always 1 for end time???
again i cant see the data nor do i understand yet how to print this info)again i tried)

im a bit closer but no joy yet, a part smile tho for i have some of it working

@Ray_Paseur:
value was not passing so it defaulted. thanks for reply. not helpful in this case, as i knew that its default(i shoulda said that too sorry) but not solution to my problem just cause of effect i guess it could be worded, again as always thanks for the insight. (i could missed that nice of you to point it out)
0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
Is this on a public-facing URL so I can look at the output as it runs?  I would like to see what we get if you add this instruction at line 55.
var_dump($doc);

Open in new window

0
 

Author Comment

by:Johnny
Comment Utility
ok how this is posible i dont get
 object(DOMDocument)#1 (0) { }
thats your output

snip from added code in where i placed it
//  Create a new document from the feed

    $doc = new DOMDocument();
    $doc->load( $feed );
var_dump($doc);
die;

Open in new window

0
 

Author Comment

by:Johnny
Comment Utility
@Ray_Paseur
sent you an email to your gmail of the pages im working on for live output, as i do not want to post the urls here please.
0
 

Author Comment

by:Johnny
Comment Utility
redid the lines a bit
//  Create a new document from the feed

    $doc = new DOMDocument();
    $doc->load( $feed );
echo "<br>";
var_dump($doc);
echo "<br>";
//die;

Open in new window

0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
I'm going to try this with SimpleXML functions instead of DomDocument.  You can visualize SimpleXML objects with var_dump().  Not being able to see the object is an astonishing handicap with DomDocument.
0
 

Author Comment

by:Johnny
Comment Utility
hey im open to anything we can do here, nothing is set in stone.
one thing i hate is i think its called opp, the $value>$nextvalue, if we can stay away from that id be most grateful too
0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
Actually it's called OOP for Object-Oriented Programming.  And it's unavoidable but easy to understand.  Example:

Find an element of an array: $thing = $array[$key];
Find a property of an object: $thing = $object->$key;

I'll show you how to get the information you need in a moment.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:Johnny
Comment Utility
yeah thats it OOP - Oh Ooo Poo - thats what it stand for right?! *smile* j/k
hard for me to wrap my head around it, i dont use it unless i have to. i should go get a book on it maybe and read it, maybe then ill be ok with using it, for now it hate it

thanks again for the help
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 500 total points
Comment Utility
This may not be exact, but it should give you a foundation.
See http://www.laprbass.com/RAY_temp_pern.php
<?php // RAY_temp_pern.php
error_reporting(E_ALL);

// ACTIVATE THIS IF YOU WANT TO LOOK AT THE OBJECTS
// echo "<pre>";

// REQUIRED PHP 5.1+
date_default_timezone_set('America/New_York');

// SET DATE RANGE
$right_now = date('c');
$next_week = date('c', strtotime($right_now . ' + 8 DAYS'));

// SET THE URL
$url
= 'http://www.google.com/calendar/feeds/'
. 'lcwchurch%40gmail.com/'
. 'public/full'
. '?orderby=starttime'
. '&singleevents=true'
. '&sortorder=ascending'
. "&start-min=$right_now"
. "&start-max=$next_week"
;

// ACTIVATE THIS TO SHOW THE URL
// echo PHP_EOL . $url;

// READ THE XML AND CONVERT TO OOP NOTATION
$xml = file_get_contents($url);
$xml = str_replace('gd:', 'gd_', $xml);
$obj = SimpleXML_Load_String($xml);

// ACTIVATE THIS TO SEE THE OBJECT
// var_dump($obj);

// ACCESS EACH ENTRY
$mdate = NULL;
foreach ($obj->entry as $entry)
{
    // ACTIVATE THIS TO SEE THE OBJECT
    // var_dump($entry);

    // INTERPRET THE ENTRY INTO PRINTABLE VARIABLES
    $title = (string)$entry->title;
    $href  = (string)$entry->link[0]["href"];
    $urli
    = '<a target="_blank" href="'
    . $href
    . '" />'
    . $title
    . '</a>'
    ;

    // LOCATION IS NOT ALWAYS FILLED IN
    $where = (string)$entry->gd_where["valueString"];
    if (!empty($where)) $where = " at $where";

    // MAKE APPROPRIATE DATE AND TIME STRINGS
    $start = (string)$entry->gd_when["startTime"];
    $ended = (string)$entry->gd_when["endTime"];
    $date  = date('l jS \of F', strtotime($start));
    $stime = date('g:i a', strtotime($start));
    $etime = date('g:i a', strtotime($ended));

    // IF WE NEED TO CHANGE THE DATE
    if ($mdate != $date)
    {
        if ($mdate)
        {
            echo PHP_EOL . "</p>";
        }
        $mdate = $date;
        echo PHP_EOL . "<p>";
        echo PHP_EOL . "<b>$date</b>";
    }

    // LIST THIS ENTRY
    echo PHP_EOL . "<br/>$stime till $etime - <b>$urli</b> $where";
}
echo PHP_EOL . "</p>";

Open in new window

0
 

Author Comment

by:Johnny
Comment Utility
WOW knock your socks off ..
better then the one i was using.
i like the layout for grouped days too


now if i can get the color of green for right now and maroon for rest of day, and some other color for all ready happened that be great, as this was my goal for today.
0
 

Author Closing Comment

by:Johnny
Comment Utility
as always grate fantastic, wonderful.

thanks so much
0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
Thanks for the points.  And best of luck with it.  I'm sure you'll get the coloring right as you get an understanding of the date representations.  All the best, ~Ray
0
 

Author Comment

by:Johnny
Comment Utility
wow i cant say enough on how i like this layout a lot better, thanks ever so much
0
 

Author Comment

by:Johnny
Comment Utility
one small problem, how can the output be by time, so i dont have 12 noon then 8am in listing as it should read 8am then 12 noon
sorry i didnt see it till now
0
 

Author Comment

by:Johnny
Comment Utility
here is the update code so it looks better on the site
<h4>This Weeks Schedule</h4>
<?php // RAY_temp_pern.php
error_reporting(E_ALL);

// ACTIVATE THIS IF YOU WANT TO LOOK AT THE OBJECTS
// echo "<pre>";

// REQUIRED PHP 5.1+
date_default_timezone_set('America/New_York');

// SET DATE RANGE
$right_now = date('c');
$next_week = date('c', strtotime($right_now . ' + 8 DAYS'));

// SET THE URL
$url
= 'http://www.google.com/calendar/feeds/'
. 'lcwchurch%40gmail.com/'
. 'public/full'
. '?orderby=starttime'
. '&singleevents=true'
. '&sortorder=ascending'
. "&start-min=$right_now"
. "&start-max=$next_week"
;

// ACTIVATE THIS TO SHOW THE URL
// echo PHP_EOL . $url;

// READ THE XML AND CONVERT TO OOP NOTATION
$xml = file_get_contents($url);
$xml = str_replace('gd:', 'gd_', $xml);
$obj = SimpleXML_Load_String($xml);

// ACTIVATE THIS TO SEE THE OBJECT
// var_dump($obj);

// ACCESS EACH ENTRY
$mdate = NULL;
foreach ($obj->entry as $entry)
{
    // ACTIVATE THIS TO SEE THE OBJECT
    // var_dump($entry);

    // INTERPRET THE ENTRY INTO PRINTABLE VARIABLES
    $title = (string)$entry->title;
    $href  = (string)$entry->link[0]["href"];
    $urli
    = '<a target="_blank" href="'
    . $href
    . '" />'
    . $title
    . '</a>'
    ;

    // LOCATION IS NOT ALWAYS FILLED IN
    $where = (string)$entry->gd_where["valueString"];
    if (!empty($where)) $where = " at $where";

    // MAKE APPROPRIATE DATE AND TIME STRINGS
    $start = (string)$entry->gd_when["startTime"];
    $ended = (string)$entry->gd_when["endTime"];
    $date  = date('l jS \of F', strtotime($start));
    $stime = date('g:i a', strtotime($start));
    $etime = date('g:i a', strtotime($ended));

    // IF WE NEED TO CHANGE THE DATE
    if ($mdate != $date)
    {
        if ($mdate)
        {
            echo PHP_EOL . "</p>";
        }
        $mdate = $date;
        echo PHP_EOL . "<p>";
        echo PHP_EOL . "<b style='color:black;'>$date</b>";
    }

    // LIST THIS ENTRY
    echo PHP_EOL . "<br/><SMALL><strong title='".$where."'>$urli</strong> $stime/$etime</SMALL>";
}
echo PHP_EOL . "</p>";

Open in new window

0
 

Author Comment

by:Johnny
Comment Utility
never mind im a dummy i read it wrong it is doing a listing in time.
forget what i said
0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
I do that, too.  It's just ordered the way Google returns it.  Sorting XML is kind of awkward, so as long as Google gets it right, I would just use it that way.  Cheers, ~Ray
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Suggested Solutions

I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Many times as a report developer I've been asked to display normalized data such as three rows with values Jack, Joe, and Bob as a single comma-separated string such as 'Jack, Joe, Bob', and vice versa.  Here's how to do it. 
This Micro Tutorial will demonstrate importing calendar invites from events such as webinars into your Google Calendar.
This Micro Tutorial will demonstrate using Google Doc how to import live data to another spreadsheet in Google Spreadsheets using the IMPORTRANGE function.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now