{"id":26586,"date":"2016-11-26T03:01:14","date_gmt":"2016-11-25T17:01:14","guid":{"rendered":"http:\/\/www.rjmprogramming.com.au\/ITblog\/?p=26586"},"modified":"2023-04-20T16:53:19","modified_gmt":"2023-04-20T06:53:19","slug":"calendar-ical-integration-timezone-tutorial","status":"publish","type":"post","link":"https:\/\/www.rjmprogramming.com.au\/ITblog\/calendar-ical-integration-timezone-tutorial\/","title":{"rendered":"Calendar iCal Integration Timezone Tutorial"},"content":{"rendered":"<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/ics_attachment.php\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Calendar iCal Integration Timezone Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/PHP\/ics_attachment_tz.jpg\" title=\"Calendar iCal Integration Timezone Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">Calendar iCal Integration Timezone Tutorial<\/p><\/div>\n<p>You might have thought with yesterday&#8217;s <a title='Calendar iCal Integration Primer Tutorial' href='#ciipt'>Calendar iCal Integration Primer Tutorial<\/a>&#8216;s emphasis on timezones we&#8217;d have &#8230;<\/p>\n<ul>\n<li>had too much<\/li>\n<li>seen too little<\/li>\n<li>invited Goldilocks for some porridge<\/li>\n<\/ul>\n<p> &#8230; but <i>time<\/i> is quite a complex scenario on Earth, when it comes to timezones for at least two reasons, one being a functional improvement, and one being to fix a bug, that being &#8230;<\/p>\n<ol>\n<li>things like WebEx or Skype or GoTo Meeting are not tied down by geography and you may want Calendar functionality to reflect this, or you may also want it to cater for airplane departure and arrival times in various timezones around the world, and it would be best if the HTML form user entry phase catered for a user specifying a date and time not necessarily in either of their <i>local<\/i> timezone nor the <i>GMT<\/i> timezone (of the iCal &#8220;Z&#8221; property special interest) &#8230; is the functional improvement, whereas &#8230;<\/li>\n<li>we had a bug, leaving off from yesterday&#8217;s work with timezones whose GMT offset involved half hour differences &#8230; and yes, that happens quite often &#8230; and the bug will occur as of yesterday&#8217;s code when you come to use those PHP DateTime object <i>add<\/i> and\/or <i>sub<\/i> methods where the PT[offset]H argument has an [offset] involving a decimal point, so it behoves us to update that relevant PHP code snippet for you, again, below, regarding that (and remind &#8230; forgot yesterday &#8230; that <i>$ts<\/i> variable is a user HTML form passed date and time) &#8230;<br \/>\n<code><br \/>\n      $di=\"PT\" . str_replace(\"-\",\"\",(\"\" . $start_end_offsets[$thisi])) . \"H\";<br \/>\n      $parsed_date = DateTime::createFromFormat('Ymd:His', $ts);<br \/>\n      if (strpos((\"\" . $start_end_offsets[$thisi]), \"-\") !== false) {<br \/>\n\t  if (strpos($di, \".\") !== false) {<br \/>\n      $parsed_date->sub(new DateInterval(explode(\".\",$di)[0] . \"H\"));<br \/>\n      $parsed_date->sub(new DateInterval(\"PT30M\"));<br \/>\n\t  } else {<br \/>\n      $parsed_date->sub(new DateInterval($di));<br \/>\n      }<br \/>\n      } else {<br \/>\n\t  if (strpos($di, \".\") !== false) {<br \/>\n      $parsed_date->add(new DateInterval(explode(\".\",$di)[0] . \"H\"));<br \/>\n      $parsed_date->add(new DateInterval(\"PT30M\"));<br \/>\n\t  } else {<br \/>\n      $parsed_date->add(new DateInterval($di));<br \/>\n      }<br \/>\n      }<br \/>\n      $outts = $parsed_date->format('Ymd:His');<br \/>\n<\/code>\n<\/li>\n<\/ol>\n<p>Now allowing for the first idea above is not as involved as you may think, but only if you think serverside PHP, rather than think it will be easy with clientside Javascript.  And what makes it a doddle, generally, are all those Open Source contributors to knowledge out there, and those great computing program language documenters out there exemplified in their brilliance with this totally useful link to the PHP <a target=_blank title='PHP timezone_identifiers_list method information' href='http:\/\/php.net\/manual\/en\/function.timezone-identifiers-list.php'>timezone_identifiers_list<\/a> and PHP DateTimeZone object method <a target=_blank title='PHP DateTimeZone object getOffset method information' href='http:\/\/php.net\/manual\/en\/function.timezone-offset-get.php'>getOffset<\/a> method links.  So we allow the user to enter any of &#8230;<\/p>\n<ul>\n<li>Local<\/li>\n<li>GMT<\/li>\n<li>Any of the half hour timezone numerical offset (indicators) from -24 to 24<\/li>\n<li>Any of the timezone names as per those PHP methods above, with valid continental prefix names<\/li>\n<\/ul>\n<p> &#8230; to define the start and end date and time parameters to express for their Calendar iCal Event that they define.  Along the way we also add in dropdowns and HTML input type=number (year) elements to help for those not so keen on keyboard entry.<\/p>\n<p>Guess you&#8217;d say we are still on the &#8220;tool&#8221; feel of the web application, but aim to move more on the &#8220;integration&#8221; front into the future.<\/p>\n<p>Here is the renewed PHP code you could call <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/ics_attachment.php-GETME\">ics_attachment.php<\/a>, that changed in <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/PHP\/ics_attachment.php-GETME\">this way<\/a>, able to be run with this <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/ics_attachment.php\" title=\"Click picture\">live run<\/a> link.  We hope you try it out for yourself, especially as we&#8217;ve added some Google Chart Map Chart linking of the &#8220;when&#8221; and &#8220;where&#8221; of defined timezone thinking, via the use of PHP&#8217;s DateTimeZone object method <a target=_blank title='PHP DateTimeZone object getOffset method information' href='http:\/\/php.net\/manual\/en\/datetimezone.getlocation.php'>getLocation<\/a>, as you can see happening with today&#8217;s <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/ics_attachment_tz.jpg\" title='Tutorial picture'>tutorial picture<\/a>.<\/p>\n<hr>\n<p id='ciipt'>Previous relevant <a target=_blank title='Calendar iCal Integration Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/calendar-ical-integration-primer-tutorial'>Calendar iCal Integration Primer Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/ics_attachment.php\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Calendar iCal Integration Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/PHP\/ics_attachment.jpg\" title=\"Calendar iCal Integration Primer Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">Calendar iCal Integration Primer Tutorial<\/p><\/div>\n<p>Do you remember us talking about the ICS extension file when we presented <a title='WebEx Prerecording Primer Tutorial' href='#wppt'>WebEx Prerecording Primer Tutorial<\/a> as shown below?   It is an integration input to working with iCal Calendar software.<\/p>\n<p>So here we are at a &#8220;when&#8221; of life tutorial, which is always an interesting exercise in our book.  And &#8220;book&#8221; could be the go for an application to use this type of functionality.  When you &#8220;book&#8221; something, you&#8217;d often want to remind yourself and\/or others of such an event.   But for now, we are concentrating on making a &#8220;tool&#8221; type of web application that will suit future purposes.<\/p>\n<p>We&#8217;ve built a web application around the useful logic presented in <a target=_blank title='Useful link' href='https:\/\/gist.github.com\/vtedesco\/5671155'>this great Git repository<\/a> today, writing our code in PHP, because you are dealing with header manipulation here centering around &#8230;<\/p>\n<p><code><br \/>\n\theader('Content-type: text\/calendar; charset=utf-8');<br \/>\n\theader('Content-Disposition: attachment; filename=rjmprogramming-event.ics');<br \/>\n\techo $ical;<br \/>\n<\/code><\/p>\n<p> &#8230; where the PHP variable <i>$ical<\/i> contents has been pieced together in response to a callback from an earlier HTML form execution of the same <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/ics_attachment.php_GETME\">ics_attachment.php<\/a> code where the necessary details are collected off the user.<\/p>\n<p>If you try the <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/ics_attachment.php\" title=\"Click picture\">live run<\/a> you&#8217;ll probably glean that most of our concern centered around the date and time, regarding timezone use so that we &#8230;<\/p>\n<ul>\n<li>in the HTML form execution we use client Javascript to glean the local timezone and local date and time to default the form appropriately &#8230; so that &#8230;<\/li>\n<li>in the HTML form execution the user fills out Calendar Event start and end times with respect to local time and this, along with an offset to get these times back to UTC or (Greenwich Mean Time) are passed to the callback web application (which is the same web application) &#8230; so that &#8230;<\/li>\n<li>the second callback execution constructs the iCal (for an rjmprogramming-event.ics attachment) with these UTC (or GMT) date and times in mind, whereby the &#8220;Z&#8221; timezone parameter fits the bill nicely &#8230; and when &#8230;<\/li>\n<li>the user saves this rjmprogramming-event.ics event into the iCal Calendar application, where the event will be shown back relative to the local date and time<\/li>\n<\/ul>\n<p>The date and time functions used to make this happen are &#8230;<\/p>\n<ol>\n<li>Javascript&#8217;s <b>Date<\/b> object &#8230;<br \/>\n<code><br \/>\n  var dd=new <b>Date<\/b>();<br \/>\n  var qw=eval((eval(dd.<i>toTimeString<\/i>().replace('-',' ').replace('+',' ').split(' ')[2]) - eval(dd.<i>toTimeString<\/i>().replace('-',' ').replace('+',' ').split(' ')[2] % 100)) \/ 100) + eval((0.0 + eval(dd.<i>toTimeString<\/i>().replace('-',' ').replace('+',' ').split(' ')[2] % 100)) \/ 60.0);<br \/>\n  if (dd.<i>toTimeString<\/i>().indexOf('+') != -1) qw=-qw;<br \/>\n  document.getElementById('tz').value=qw;<br \/>\n<\/code>\n<\/li>\n<li>Javascript&#8217;s Date object&#8217;s <i>toTimeString<\/i> method (as shown above) to glean the local timezone offset, and its opposite<\/li>\n<li>PHP&#8217;s <b>DateTime<\/b> object &#8230;<br \/>\n<code><br \/>\n      $di=\"PT\" . str_replace(\"-\",\"\",urldecode($_POST['tz'])) . \"H\";<br \/>\n      $parsed_date = <b>DateTime::<\/b><i>createFromFormat<\/i>('Ymd:His', $ts);<br \/>\n      if (strpos(urldecode($_POST['tz']), \"-\") !== false) {<br \/>\n      $parsed_date-><i>sub<\/i>(new <b><i>DateInterval<\/i><\/b>($di));<br \/>\n      } else {<br \/>\n      $parsed_date-><i>add<\/i>(new <b><i>DateInterval<\/i><\/b>($di));<br \/>\n      }<br \/>\n      $outts = $parsed_date-><i>format<\/i>('Ymd:His');<br \/>\n<\/code><\/p>\n<li>PHP&#8217;s DateTime object&#8217;s <i>createFromFormat<\/i> constructor method (as above) to create a DateTime object from the passed through user details<\/li>\n<li>PHP&#8217;s <b><i>DateInterval<\/i><\/b> object<\/li>\n<li>PHP&#8217;s DateTime object&#8217;s <i>add<\/i> and\/or <i>sub<\/i> methods (as above) to create a DateTime object with a DateInterval offset to UTC (or GMT) (expressed in hours)<\/li>\n<li>PHP&#8217;s DateInterval object&#8217;s <i>format<\/i> method (as above) to end up with a UTC (or GMT) expression of date and time to be placed into the rjmprogramming-event.ics iCal message<\/li>\n<\/ol>\n<p>We&#8217;ll probably be revisiting with improvements soon, but we hope you try it for yourself.<\/p>\n<hr>\n<p id='wppt'>Previous relevant <a target=_blank title='WebEx Prerecording Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/webex-prerecording-primer-tutorial\/'>WebEx Prerecording Primer Tutorial<\/a> is shown below.<\/p>\n<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/WebEx\/\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"WebEx Prerecording Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/WebEx\/webex.jpg\" title=\"WebEx Prerecording Primer Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">WebEx Prerecording Primer Tutorial<\/p><\/div>\n<p>We&#8217;ve been trying out <a target=_blank title='WebEx video conferencing' href='https:\/\/www.webex.com\/'>WebEx<\/a> (by <a target=_blank title='Cisco' href='http:\/\/www.cisco.com'>Cisco<\/a>) prerecording as a video conferencing idea as an alternative to &#8230;<\/p>\n<ul>\n<li><a target=_blank href='http:\/\/www.gotomeeting.com\/'>GoToMeeting<\/a> (by <a target=_blank title='Citrix' href='http:\/\/www.citrix.com'>Citrix<\/a>) we talked about with <a target=_blank title='GoToMeeting Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/gotomeeting-primer-tutorial\/'>GoToMeeting Primer Tutorial<\/a><\/li>\n<li><a target=_blank href='http:\/\/www.skype.com'>Skype<\/a> (by Skype and now <a target=_blank href='http:\/\/www.microsoft.com\/'>Microsoft<\/a>) we talked about with <a target=_blank title='Skype Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/skype-primer-tutorial\/'>Skype Primer Tutorial<\/a><\/li>\n<\/ul>\n<p> &#8230; regarding video conferencing products we&#8217;ve tried at this blog.<\/p>\n<p>Have to say, WebEx is great, even with respect to the &#8220;wide eyed and bushy tailed&#8221; reaction &#8220;this little black duck&#8221; has to all these networky communicaty ideas on the net (at least we spelt &#8220;net&#8221; correctly).<\/p>\n<p>Have to thank my wife, Maree, for her expertise and the facilities her company, <a target=_blank title='Thomson Reuters home page' href='http:\/\/thomsonreuters.com\/'>Thomson Reuters<\/a>, supplies for the serving of WebEx recordings &#8230; thanks everyone.  Have been assured they are periodically deleted, and my lame impersonations of the old &#8220;ducks on the wall&#8221; can rest in peace shortly.<\/p>\n<p>And so, we have a <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/WebEx\/\" title='Click picture'>slideshow<\/a> starting with a WebEx email link to join a meeting, and we pan down the email to show you other WebEx functionalities, such as adding a Calendar reference to the meeting time, and though we haven&#8217;t shown you detail here, rest assured it handles timezone scenarios very well, unless you lie about living in Antarctica, that is<font size=1> &#8230; sorry, scientists in Antarctica reading this blog posting &#8230; all 237 of you<\/font>.<\/p>\n<p>During this &#8220;earlier than today exploration of WebEx&#8221; session the necessary software installs just happened for this MacBook Pro Mac OS X laptop as if we were shelling peas<font size=1> &#8230; it&#8217;s always good to have some handy when installing any software<\/font>.  So we won&#8217;t show you this unless we deem it essential at a later date.  You can perhaps do as I did, and ask a real WebEx user invite you to a meeting, to set yourself up.  In fact, today&#8217;s session meeting creation time you may notice is well in the past from that earlier introductory learning session Maree and I had, and you can bring back up that old email, and resurrect that meeting again and again, if you like<font size=1> &#8230; am not sure if there is an expiry date on this too, like with server stored WebEx prerecordings<\/font>.<\/p>\n<p>So also rest assured, WebEx handles &#8230;<\/p>\n<ul>\n<li>video via webcam on your device<\/li>\n<li>audio via microphone on your device (&#8220;Use Computer&#8221;) or via a phone line<\/li>\n<li>the synchronization of the two above<\/li>\n<li>mobile devices<\/li>\n<\/ul>\n<p><b><i>Did you know?<\/i><\/b><\/p>\n<p>A .ics extension file, as you can see being used as an email attachment file extension in <img src='http:\/\/www.rjmprogramming.com.au\/WebEx\/webexte.jpg' title='Extension .ics'><\/img> is, as explained in <a target=_blank title='https:\/\/www.google.com.au\/#q=ics+file&#038;gws_rd=cr'>this link<\/a>&#8216;s <a target=_blank title='Useful link' href='http:\/\/www.online-convert.com\/file-format\/ics'>sublink<\/a> &#8230;<\/p>\n<blockquote><p>\nICS is a global format for calendar files widely being utilized by various calendar and email programs including Google Calendar, Apple iCal, and Microsoft Outlook. These files enable users to share and publish information directly from their calendars over email or via uploading it to the world wide web.\n<\/p><\/blockquote>\n<p> &#8230; as helping interface meetings to online calendar appointments.  Cute, huh?!<\/p>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d21840' onclick='var dv=document.getElementById(\"d21840\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/video-conferencing\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d21840' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d26567' onclick='var dv=document.getElementById(\"d26567\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/calendar\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d26567' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d26586' onclick='var dv=document.getElementById(\"d26586\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/timezone\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d26586' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n","protected":false},"excerpt":{"rendered":"<p>You might have thought with yesterday&#8217;s Calendar iCal Integration Primer Tutorial&#8216;s emphasis on timezones we&#8217;d have &#8230; had too much seen too little invited Goldilocks for some porridge &#8230; but time is quite a complex scenario on Earth, when it &hellip; <a href=\"https:\/\/www.rjmprogramming.com.au\/ITblog\/calendar-ical-integration-timezone-tutorial\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,37],"tags":[180,2066,301,302,367,452,519,1996,576,2064,2065,652,932,997,1168,1279,1693,1319],"class_list":["post-26586","post","type-post","status-publish","format-standard","hentry","category-elearning","category-tutorials","tag-calendar","tag-callback","tag-date","tag-datetime","tag-dropdown","tag-form","tag-google-charts","tag-header","tag-html","tag-ical","tag-interval","tag-javascript","tag-php","tag-programming","tag-software-integration","tag-time","tag-timezone","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/26586"}],"collection":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/comments?post=26586"}],"version-history":[{"count":11,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/26586\/revisions"}],"predecessor-version":[{"id":59035,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/26586\/revisions\/59035"}],"wp:attachment":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/media?parent=26586"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/categories?post=26586"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/tags?post=26586"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}