Link to home
Start Free TrialLog in
Avatar of Johnny
JohnnyFlag for United States of America

asked on

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
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

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.
https://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_201-Handling-date-and-time-in-PHP-and-MySQL.html
Avatar of Johnny

ASKER

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)
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

Avatar of Johnny

ASKER

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

Avatar of Johnny

ASKER

@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.
Avatar of Johnny

ASKER

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

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.
Avatar of Johnny

ASKER

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
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.
Avatar of Johnny

ASKER

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
ASKER CERTIFIED SOLUTION
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Johnny

ASKER

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.
Avatar of Johnny

ASKER

as always grate fantastic, wonderful.

thanks so much
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
Avatar of Johnny

ASKER

wow i cant say enough on how i like this layout a lot better, thanks ever so much
Avatar of Johnny

ASKER

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
Avatar of Johnny

ASKER

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

Avatar of Johnny

ASKER

never mind im a dummy i read it wrong it is doing a listing in time.
forget what i said
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