php xml parse Google calendar events - end time

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
JohnnyAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ray PaseurCommented:
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
JohnnyAuthor Commented:
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
Ray PaseurCommented:
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
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

JohnnyAuthor Commented:
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
JohnnyAuthor Commented:
@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
JohnnyAuthor Commented:
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
Ray PaseurCommented:
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
JohnnyAuthor Commented:
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
Ray PaseurCommented:
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
JohnnyAuthor Commented:
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
Ray PaseurCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
JohnnyAuthor Commented:
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
JohnnyAuthor Commented:
as always grate fantastic, wonderful.

thanks so much
0
Ray PaseurCommented:
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
JohnnyAuthor Commented:
wow i cant say enough on how i like this layout a lot better, thanks ever so much
0
JohnnyAuthor Commented:
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
JohnnyAuthor Commented:
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
JohnnyAuthor Commented:
never mind im a dummy i read it wrong it is doing a listing in time.
forget what i said
0
Ray PaseurCommented:
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.