Keeping local time across time zones?

WordPress Event Management, Calendars & Registration Forums iCal Extension Keeping local time across time zones?

This topic contains 8 replies, has 2 voices, and was last updated by  Beth Moeller 9 years, 9 months ago.

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #14397

    Hello,

    I’ve read through some of the other threads and don’t see this. We are importing calendars from multiple time zones and we want to retain the original time of the event.

    For example, I have an export from a site with a Chicago timezone and am importing it to a New York website. There is a 1 hour difference. All the events are showing in New York time. Due to the nature of this site, we want them to retain their local time.

    Any suggestions?

    Beth

    Beth Moeller
    #14403

    Hi Beth,

    This isn’t a straightforward task as the underlying assumption in the plug-in is that the all events are in the same timezone. However they are a filters which allow you to modify the event’s date for the purposes of it being displayed.

    When importing a feed, all datetimes are converted to the blog’s timezone (at the point they are inserted into the database). What these means is that you should be able to use the hooks eventorganiser_ical_sync_event_inserted/eventorganiser_ical_sync_event_updated to check the start time of the event (which is DateTime object) and specifically its timezone (DateTimeZone object). You could then store that timezone (store the name not the object – some servers won’t like it!) along with the event as post meta (events are a post type).

    The plug-in will typically display the event’s start date/time using eo_get_the_start() – this calls the eventorganiser_get_the_start (see codex). This would allow to change the timezone as follows:

    add_filter( 'eventorganiser_get_the_start', 'my_callback_function', 10, 5 );
    function my_callback_function( $formatted_start, $start, $format, $post_id, $occurrence_id ){
        $timezone = get_post_meta( $post_id, 'event_timezone' );
        $timezoneobj = new DateTimeZone( $timezone );
        if( $timezoneobj ){
              $start->setTimezone( $timezoneobj  );
        }
        //Change first value and return it
        return eo_format_datetime( $start, $format );
    
    };
    

    Word of warning: I’m not sure how the calendar would react to the timezone being changed since the underlying assumption in the plug-in is that the timezone is universal. So you may want to not change the timezone when in AJAX (check: defined( 'DOING_AJAX') && DOING_AJAX) or admin-side (check is_admin() ). Lastly there may be instances where the plug-in doesn’t use eo_get_the_start() put loops through eo_get_the_occurrences_of() or eo_get_the_future_occurrences_of() – these also have filters which you can use.

    Stephen Harris
    #14792

    Hi Stephen,

    I’ve been doing some more digging. The .ics file I have been testing with (http://peteweise.com/feed/eo-events) does not include the VTIMEZONE or TZID timezone designators in it. Therefore, it’s not possible for me to store the timezone data in postmeta.

    I see two options:

    1. Add the time zone through the Add a feed function and parse the
      incoming data using that time zone. We store it in post meta and use the filter you suggested above.

    2. Use the existing category structure I have in place to help define the time zone difference from our site settings. I could then store the difference somewhere and add a different filter for the data display.

    I’m leaning toward the first option, as i think it would be more reliable and permanent. I’m willing to give it a shot on one of my installations and let you know what I find.

    Thoughts?

    Beth

    Beth Moeller
    #14795

    Hi Beth,

    That iCal source is from an Event Organiser (powered) site – and so the timezone is the same for all events (the site timezone). Datetimes are all given in UTC timezone (as this the most interoperable way of conveying the information).

    If you know all events are going to be from one particular timezone, then either (1) or (2) could work. The advantage of (2) is that it avoids having to make (and maintain) changes to the core code.

    A third, perhaps overly complicated way, would be to use the event’s geo coordinates to lookup the appropriate timezone. You can cache this so the same co-ordinates aren’t looked up more than once (and only look up the timezone if the location has changed). This option has the advantage of supporting iCal feeds with events in multiple timezones, The disadvantage is that it requires the event has a GEO tag supplied. Also you would need to map the timezone you get from the service you use to a PHP timezone (might not always be easy!),

    Stephen Harris
    #14796

    Hi Stephen,

    I knew it was an EO powered site — I set it up. I have seen some ics files that include the timezone. Since I won’t necessarily know what time zone people have setup on their sites (some don’t know to change it out of UTC), I need a way to figure out that time zone.

    I’ll look at #2 in some more detail.

    Where would you put the filter?

    Beth

    Beth Moeller
    #14818

    Ah ok 😉

    I would create a site-utility plug-in for it.(It would work in your theme’s functions.php, but this would create extra hassle when changing themes).

    Stephen Harris
    #14851

    So close, but having issues with the return. Script below, based on the script you provided above. I created a table that associates my categories with a timezone in name format (i.e. America/New York). Everything is working. We get the date, category, set the timezone, and I have the new start time based on the category time zone. I have $start returning a DateTime object. When this runs, the print statement tells me I’m doing everything correctly from a calculation standpoint, but it doesn’t seem to be returning the data.

    You can see this running at http://arts-spark.com/tz-test/. Obviously, it’s not my functions file yet. The function is at the top of the page and then I use a basic [eo_events] to call the list of events. This page should offset everything by 1 hour.

    add_filter( 'eventorganiser_get_the_start', 'my_callback_function', 10, 5 ); 
    function my_callback_function( $formatted_start, $start, $format, $post_id, $occurrence_id ){
    
                if ($post_id) {  // make sure we have a post_id otherwise it will kick out errors
    
                    //get catid
                    $feedid = get_post_meta( $post_id, '_eventorganiser_feed',true );
                    $catid = get_post_meta( $feedid, '_eventorganiser_feed_category',true );
    
                    //get correct timezone - just quick sql query
                    $tzcmd = "select timezone from category_zone where catid='$catid';";
                    $tzres = mysql_query($tzcmd);
                    $tzrow = mysql_fetch_row($tzres);
                    $tz = $tzrow[0];
    
                    $currentzone = new DateTimeZone('America/New_York');
                    $displayzone = new DateTimeZone ($tz);
    
                    $formstart = $start->format('Y-m-d H:i:s'); // convert so we can create new datetime object
    
                    $newstart = new DateTime($formstart, $currentzone);
                    $newstart->setTimezone($displayzone);
    
                    $start = $newstart;
    
                    $displaynewstart = $newstart->format('Y-m-d H:i:s');
    
                    print "

    formstart: $formstart, displaynewstart: $displaynewstart

    \n"; return eo_format_datetime($start,$format); } };

    Any other suggestions?

    • This reply was modified 9 years, 10 months ago by  Beth Moeller.
    Beth Moeller
    #14864

    You’ve found a bug – the $post_id variable should never be empty, but in some instances it is.

    There’s an easy fix for this in your code (although it won’t be required once Event Organiser is updated), but simple remove the if( $post_id){ ... } conditional and at the top of your callback:

    $post_id = (int) ( empty( $post_id ) ? get_the_ID() : $post_id );
    
    Stephen Harris
    #14897

    Thanks! That did it!

    Beth

    Beth Moeller
Viewing 9 posts - 1 through 9 (of 9 total)
To enable me to focus on Pro customers, only users who have a valid license for the Pro add-on may post new topics or replies in this forum. If you have a valid license, please log-in or register an account using the e-mail address you purchased the license with. If you don't you can purchase one here. Or there's always the WordPress repository forum.