Solved

Event times displayed on website output (event listing by time) convert to event time

Posted on 2013-11-05
20
337 Views
Last Modified: 2013-11-05
ok so much for a title that makes sense!!

i have a site that outputs events start and end date-time.
the server time is in denver, co usa so its time is GMT -7
i have events all over the place in the world, id like to show the time in their location of the event, not in denver as it is shown now (as its saved to mysql).

so i wrote a nifty php script that converts the long,lat to nearest timezone.
nearest_tz_lat_lng.php
?q=57.150001525878906,-2.0999999046325684
outputs:
Europe/Isle_of_Man, BDST, +00:00
or
?q=40.772222,-74.164581,US
outputs:
America/New_York, EDT, -05:00

id like to use this as my check i assume the offset last var with split comma is what is needed here.
so if i have
  $start_event=date('D,M jS Y g:i a', strtotime($row['event_start'])); 
  $end_event=date('D,M jS Y g:i a', strtotime($row['event_end']));

Open in new window


how do i get a variable of $event_local_time_start to be the correct time please.

some info i have so far
           echo "*********************<br>";
              echo "<b>Testing Mode</b> <br>";
              echo "Users timezone: ";
               echo "".$_SESSION['users_timezone'];
              echo "<br>";
              echo "Server Timezone ";
              print date_default_timezone_get();
              echo "<br>";
              echo "Server TimeZone get: ";
              $dt = new DateTime();
              print $dt->getTimeZone()->getName();
              echo "<br>";
              echo "Server Time now: ";
              print date("r", strtotime("now"));
              echo "<br>";
              echo "---------------------<br>";
              $theTime = time(); # specific date/time we're checking, in epoch seconds. 

                $server_tz=date_default_timezone_get();
                $tz = new DateTimeZone($server_tz); 
                $transition = $tz->getTransitions($theTime,$theTime); 
                
                # only one array should be returned into $transition. Now get the data: 
                $offset = $transition[0]['offset']; 
                $abbr = $transition[0]['abbr']; 
                echo "Time offset: ".$offset;
                echo "<br>";
                echo "Time abr: ". $abbr;
                echo "<br>";
                $offsetHours = round(abs($offset)/3600); 
                $offsetMinutes = round((abs($offset) - $offsetHours * 3600) / 60); 
                $offsetString = ($offset < 0 ? '-' : '+') 
                . ($offsetHours < 10 ? '0' : '') . $offsetHours 
                . ':' 
                . ($offsetMinutes < 10 ? '0' : '') . $offsetMinutes;
                echo "Converted offset to hours/mins: ".$offsetString;
                echo "<br>"; 
                echo "*********************<br>";

Open in new window


outputs:
*********************
Testing Mode 
Users timezone: GMT -5
Server Timezone America/Denver
Server TimeZone get: America/Denver
Server Time now: Tue, 05 Nov 2013 13:05:20 -0700
---------------------
Time offset: -25200
Time abr: MST
Converted offset to hours/mins: -07:00
*********************

Open in new window


my lat long strings are
$row['lat']
$row['lng']

Open in new window


if i understand this right i have to capture: (offset numbers from GMT)
 the servers time zone (supplied code for that) with offset number
 the events time zone offset number
supply the start date/time, event end date/time (supplied that)
 *** here the part i do not understand or how to calc in php***
take the offset times calc the difference
take this and add or subtract from current denver time frames.
this should show the events local time ????

can i have tried to do this but it gets all botched up. shows a date way in the future and sometimes off by a day or two so im asking here.
i think i provided all the code i have so far. please ask if i have missed anything.
thank you for your time in this matter

thank you in advance for any code or help you may provide.
0
Comment
Question by:Johnny
  • 11
  • 6
  • 3
20 Comments
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39625820
This may be easier if you know the location by name, rather than by LAT/LON.  Check the man page notes here:
http://php.net/manual/en/datetimezone.getlocation.php

I'll try to get you an example that works backward from LAT/LON to a time zone.  In any case, you may want to let the client tell the local date and time, and you just keep that in the data base, without interpretation or alloying of your current locale.

Please post a short list of LAT/LON pairs that represent your test data, thanks.
0
 
LVL 58

Expert Comment

by:Gary
ID: 39625839
Think  you are over complicating it...

$utc = new DateTimeZone("MST"); 
$timezone = new DateTimeZone("Europe/Isle_of_Man"); // Pass in the timezone to convert to
$date = new DateTime(date('Y-m-d h:m:s', strtotime($row['event_start'])), $utc);
$date->setTimezone( $timezone);
echo $date->format('H:i:s');

Open in new window


How are the dates/time stored in the db? In Denver time?

Edited to fix error
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39625854
I may not be able to give you anything finished this evening, but this would be a start.
http://www.laprbass.com/RAY_dateTimeZone.php

Using that information, it seems like we can create a data base table that contains the names of the time zones and the LAT/LON pairs.  Then we can use the Haversine formula to compute the time zones that are closest to the destination.  This will give us an imperfect, but educated guess.

The problem with this approach would be things like China (one time zone) and "America/Denver" which is truly the time zone for a great many LAT/LON pairs, including Utah, part of Idaho, part of Oregon and all of Arizona, except during daylight saving time (unless you're looking at the Navajo nation).  Maybe there is something in the DateTimeZone class that I have not discovered yet (I hope so)!

<?php // RAY_dateTimeZone.php
ini_set('display_errors', TRUE);
error_reporting(E_ALL);
echo '<pre>';

// MAN PAGE REFS:
// http://php.net/manual/en/class.datetimezone.php

ob_start();
$cnt = 0;
$tzs = DateTimeZone::listIdentifiers();
foreach ($tzs as $key => $zone)
{
    $cnt++;
    $dtz = new DateTimeZone($zone);
    $loc = $dtz->getLocation();
    echo PHP_EOL . "<b>$zone</b>  ";
    print_r($loc);
}
$out = ob_get_clean();
echo "<h2>$cnt TIME ZONES</h2>";
echo $out;

Open in new window

0
 

Author Comment

by:Johnny
ID: 39625890
this is my code for the nifty find info from lat,lng
<?
//****************************************************************
// Filename..: __.php
// Author....: __
// Date......: mm/dd/yyyy
// Purpose...: __
// SQL.......: server/database/tables/tablename
//****************************************************************
// include("filename.php");


function get_timezone_abbreviation($timezone_id)
{
    if($timezone_id){
        $abb_list = timezone_abbreviations_list();

        $abb_array = array();
        foreach ($abb_list as $abb_key => $abb_val) {
            foreach ($abb_val as $key => $value) {
                $value['abb'] = $abb_key;
                array_push($abb_array, $value);
            }
        }

        foreach ($abb_array as $key => $value) {
            if($value['timezone_id'] == $timezone_id){
                return strtoupper($value['abb']);
            }
        }
    }
    return FALSE;
}



function get_nearest_timezone($cur_lat, $cur_long, $country_code = '') {
    $timezone_ids = ($country_code) ? DateTimeZone::listIdentifiers(DateTimeZone::PER_COUNTRY, $country_code)
                                    : DateTimeZone::listIdentifiers();

    if($timezone_ids && is_array($timezone_ids) && isset($timezone_ids[0])) {

        $time_zone = '';
        $tz_distance = 0;

        //only one identifier?
        if (count($timezone_ids) == 1) {
            $time_zone = $timezone_ids[0];
        } else {

            foreach($timezone_ids as $timezone_id) {
                $timezone = new DateTimeZone($timezone_id);
                $location = $timezone->getLocation();
                $tz_lat   = $location['latitude'];
                $tz_long  = $location['longitude'];

                $theta    = $cur_long - $tz_long;
                $distance = (sin(deg2rad($cur_lat)) * sin(deg2rad($tz_lat))) 
                + (cos(deg2rad($cur_lat)) * cos(deg2rad($tz_lat)) * cos(deg2rad($theta)));
                $distance = acos($distance);
                $distance = abs(rad2deg($distance));
                // echo '<br />'.$timezone_id.' '.$distance; 

                if (!$time_zone || $tz_distance > $distance) {
                    $time_zone   = $timezone_id;
                    $tz_distance = $distance;
                } 

            }
        }
        return  $time_zone;
    }
    return 'none?';
}

 
 $my_data=$_REQUEST['q'];
 
     if (strpos($my_data,',') !== false) {
     $cords=explode(",",$my_data);
     $lat=$cords[0];
     $lng=$cords[1];
     $cc=$cords[2];
     $tz_name = get_nearest_timezone($lat,$lng,$cc);
     echo $tz_name;
     echo ", ";
     echo get_timezone_abbreviation($tz_name);
     echo ", ";
     $timezone = new DateTimeZone($tz_name);
     $offset   = $timezone->getOffset(new DateTime);
     $offsetHours = round(abs($offset)/3600); 
     $offsetMinutes = round((abs($offset) - $offsetHours * 3600) / 60); 
     $offsetString = ($offset < 0 ? '-' : '+') 
     . ($offsetHours < 10 ? '0' : '') . $offsetHours 
     . ':' 
     . ($offsetMinutes < 10 ? '0' : '') . $offsetMinutes;
     //echo "Converted offset to hours/mins: ".$offsetString;
     echo $offsetString;
     
      //echo $offset; // mins
 }
 
 
 
 /*
"Abbotsford, BC","(GMT-08:00) Pacific Time (US & Canada); Tijuana","Canada",49.06638717651367,-122.30000305175781,"Pacific Standard Time"
"Aberdeen","(GMT) Dublin, Edinburgh, Lisbon, London","United Kingdom",57.150001525878906,-2.0999999046325684,"GMT Standard Time"

echo get_nearest_timezone(49.06638717651367,-122.30000305175781) ;
echo "<br>";
echo get_nearest_timezone(57.150001525878906,-2.0999999046325684) ;
echo "<br>";

//timezone for one NY co-ordinate
echo get_nearest_timezone(40.772222,-74.164581) ;
echo "<br>";
// more faster and accurate if you can pass the country code 
echo get_nearest_timezone(40.772222, -74.164581, 'US') ;
echo "<br>";
*/

Open in new window

0
 
LVL 58

Accepted Solution

by:
Gary earned 500 total points
ID: 39625895
Correction to the above

$mytimezone  = new DateTimeZone("EDT");
$usertimezone  = new DateTimeZone("GMT");
$date = new DateTime(date('Y-m-d h:i:s', strtotime($row['event_start'])), $usertimezone  );
$date->setTimezone($mytimezone);
echo $date->format('h:i:s');

Open in new window

0
 

Author Comment

by:Johnny
ID: 39625914
@GaryC123
i noticed just fyi that the php DST flag is wrong right now as I am in usa Ohio and it just flipped time this past weekend to EST. just fyi

the servers time zone is in Denver, Co, USA thats MST right now.
im in ohio thats EST right now


i converted your time to this for testing
$utc = new DateTimeZone("MST"); 
//$timezone = new DateTimeZone("Europe/Isle_of_Man"); // Pass in the timezone to convert to
$timezone = new DateTimeZone("America/New_York"); 
$row['event_start']="2013-11-01 20:55:00";
$date = new DateTime(date('Y-m-d h:m:s', strtotime($row['event_start'])), $utc);
$date->setTimezone( $timezone);
echo $date->format('D,M jS Y g:i a');

Open in new window


trying to figure out your code on the second set now, it looks as if your doing browser times, i don't need that right now i need the time of the event vs saved mysql database server time so denver to ohio time zones as my test
0
 

Author Comment

by:Johnny
ID: 39625930
i believe this works - testing it now

$mytimezone  = new DateTimeZone("MST");
$usertimezone  = new DateTimeZone("EST");
$row['event_start']="2013-11-05 12:30:00";
$start_event=date('D,M jS Y g:i a', strtotime($row['event_start'])); 
echo "orginal time(server): ".$start_event."<br>";
$date = new DateTime(date('Y-m-d h:i:s', strtotime($row['event_start'])), $usertimezone  );
$date->setTimezone($mytimezone);
echo "ohio time:(converted) ".$date->format('D,M jS Y g:i a');

Open in new window

0
 
LVL 58

Expert Comment

by:Gary
ID: 39625934
Use the second example, the first was wrong
Can you clarify what timezone are the events stored in the DB
My code is converting between the two time zones, nothing to do with browser timezone.

I was assuming the time was stored as MST and for example to convert it to GMT.
It is always best to store date/time in UTC if you are dealing with circumstances where you are covering multiple timezones.

So it may be best to just run a routine on your db to convert all the event date/time to UTC.
Then when you need to convert to local time it is just a one line conversion and no messing about.
0
 

Author Comment

by:Johnny
ID: 39625940
crud there's a problem that nifty code i made above for the lat.lng pulls
is not correctly pulling if its est or edt. so i cant get what the abbr time zone is

man time is hard with to manipulate, this event thing is really not worth doing.
grumble
still plugging away to find a solution
0
 
LVL 58

Expert Comment

by:Gary
ID: 39625941
See my comment above
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:Johnny
ID: 39625942
if the above lat,lng code returned the right daylight abbreviation we be all set
yes i worked with the new code(second code) as you can see now
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39625947
... php DST flag is wrong right now as I am in usa Ohio and it just flipped time this past weekend to EST.
I am in Washington, DC, and the same thing happened here.  EDT converted to DST at 2:00am on Sunday.  This was expected and correct AFAIK.  Where are you getting the incorrect DST flag?  You might do PHP and all the users a big favor if you file a bug report!
0
 

Author Comment

by:Johnny
ID: 39625948
maybe i should do that save as utc..then ask user when they input what time zone there in from a pull down...maybe
0
 

Author Comment

by:Johnny
ID: 39625968
@Ray_Paseur yeah i was gonna tackle that too soon as a bug i did a bit of digging and it uses the icann time zone tables rules here

http://www.iana.org/time-zones

http://www.iana.org/time-zones/repository/tz-link.html

apparently they missed this year i guess for correct rules(dunno)

confirm please you tested and you got the error too in php with its timezone rules? for time change?
0
 

Author Comment

by:Johnny
ID: 39625975
i am going to accept this as solved and ask another question if i get farther stuck and ill try and post here if i get anyplace on the php bug.

i still need to check event location and time zone for it match and use this new code block gary has so nicely done.
0
 

Author Closing Comment

by:Johnny
ID: 39625977
thank you Gary
0
 
LVL 58

Expert Comment

by:Gary
ID: 39625980
You don't need the abbreviation, just pass in the timezone name e.g. America/New_York - forget EST or MST etc
0
 

Author Comment

by:Johnny
ID: 39625987
fyi this works
$usertimezone  = new DateTimeZone("America/New_York");

Open in new window


 so for my code i can look that up and change my times correctly

to clarify how would i do it if my database was in UTC time please

1: save as UTC in my insert string for time (just need the convert code)
2: take it back out (as mentioned one line of code) to display as local time

sorry i do not get how we did this in the first place to make it on my own

wait would this work
$database_timezone  = new DateTimeZone("GMT");
$save_to_mysql_date_time_gmt = new DateTime(date('Y-m-d h:i:s', strtotime($time_to_save_to_mysql)), $usertimezone  );
// get back out
$usertimezone  = new DateTimeZone("America/New_York"); //local events time zone
$mysql_date_time_gmt = new DateTime(date('Y-m-d h:i:s', strtotime($time_saved_in_mysql)), $usertimezone  );

Open in new window


would that work?
0
 

Author Comment

by:Johnny
ID: 39625990

You don't need the abbreviation, just pass in the timezone name e.g. America/New_York - forget EST or MST etc
yeah you posted same time i did
0
 
LVL 58

Expert Comment

by:Gary
ID: 39626018
<?php
// Store $mydatetime in the db in UTC
//Pass in the users local time zone e.g. GMT, Europe/London etc
$mydatetime = strtotime("2013-11-05 10:00:00" ." GMT");


echo "2013-11-05 10:00:00<br><br>Converted to UTC: ".$mydatetime ."<br><br>";

$dtz = new DateTime('@'.$mydatetime);
$dtz->setTimeZone(new DateTimeZone('America/New_York'));
echo "<br>New York Time: ".$dtz->format('F j, Y, g:i a');

$dtz = new DateTime('@'.$mydatetime);
$dtz->setTimeZone(new DateTimeZone('Europe/London'));
echo "<br><br>London Time: ".$dtz->format('F j, Y, g:i a');

$dtz = new DateTime('@'.$mydatetime);
$dtz->setTimeZone(new DateTimeZone('America/Denver'));
echo "<br><br>Denver Time: ".$dtz->format('F j, Y, g:i a');

Open in new window


Edited
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Popularity Can Be Measured Sometimes we deal with questions of popularity, and we need a way to collect opinions from our clients.  This article shows a simple teaching example of how we might elect a favorite color by letting our clients vote for …
This article will explain how to display the first page of your Microsoft Word documents (e.g. .doc, .docx, etc...) as images in a web page programatically. I have scoured the web on a way to do this unsuccessfully. The goal is to produce something …
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

707 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

17 Experts available now in Live!

Get 1:1 Help Now