How to get Time Zone through IP Address in PHP [duplicate]
Asked Answered
K

9

41

I want to get time zone through an IP Address in PHP. Actually, I have an application which will run at the client machine. I have the IP address of the client machine. But I am not able to get the time zone for each client machine.

Kedgeree answered 13/4, 2009 at 10:6 Comment(1)
Try this: sanjaykumarns.blogspot.com/p/…Zerline
P
42
$ip = "189.240.194.147";  //$_SERVER['REMOTE_ADDR']
$ipInfo = file_get_contents('http://ip-api.com/json/' . $ip);
$ipInfo = json_decode($ipInfo);
$timezone = $ipInfo->timezone;
date_default_timezone_set($timezone);
echo date_default_timezone_get();
echo date('Y/m/d H:i:s');

Sometime it won't work on local server so try on server.

Edit: This data is coming from ip-api.com, they're free to use as long as you don't exceed 45 requests per minute and not using commercially. See their TOS, not a long a page.

Provincialism answered 30/3, 2017 at 14:5 Comment(1)
very helpful saved a lot of time for meSuperfuse
M
14

IP address can't even be relied upon to map to a country; you're treading on thin ice if you also want to get timezone. You're better off to have the client send you the time zone, perhaps in a header.

See Tor: anonymity online for yet another reason to stop using IP addresses for things they were not designed for.

Masera answered 13/4, 2009 at 10:52 Comment(6)
Often though you might be providing the user with "best guess" auto completed form fields in which case there's absolutely nothing wrong with this.Sanctus
Nothing wrong with what?Masera
Nothing wrong with using an ip to approximate a timezone.Sullen
I agree. If there is information that can help your UX in the right direction without harming the users interaction, use it!Ensor
@Willem: sure, but be sure to test the case where the IP address leads you in the wrong direction, like the case I mentioned: IP address from England, actual time zone US Eastern Standard.Masera
Absolutely. For sensitive areas like that I would not recommend it either but for auto-complete form fields such as @JohnHunt mentioned I like the idea.Ensor
S
11

If you're running it on the local machine, you can check the configured timezone.
http://www.php.net/manual/en/function.date-default-timezone-get.php

There are a lot better and more reliable methods then trying to guess timezone using GeoIP. If you're feeling lucky, try: http://www.php.net/manual/en/book.geoip.php

$region = geoip_region_by_name('www.example.com');
$tz = geoip_time_zone_by_country_and_region($region['country_code'],
                                            $region['region']);  
Stereotype answered 13/4, 2009 at 10:10 Comment(2)
The application is running on the local machine, but i want to get time zone through IP on the server side, not on local machine.Kedgeree
I would love to have a local copy the GeoIP timezone data.Heptavalent
M
10

There's no absolutely certain way to get the client's timezone, but if you have the client submit the date and time from their machine, you can compute it based on what the time it is relative to GMT. So, if it's 7:00pm on their machine and it's 12:00am GMT, then you can determine they are -5 from GMT or (EST/DST)

Mortician answered 13/4, 2009 at 10:30 Comment(3)
Timezones are quite difficult, as most internationalization problems are. If you know their current time AND if they are on daylight saving or not, then you can determine their timezone. Figuring out the daylight saying is however, very difficult (again)Heptavalent
This is a great idea in theory until you factor in DST. Which makes me want to cry.Nymphet
This is a great idea. And DST does not make a difference, since we always store GMT on the server anyway :)Opinion
P
9

It is not a good idea for searching the timezone of a user through his or her ip address as he can access his or her account from different places at different times. So it is impossible to locate his timezone through ip address. But I have tried to find a solution and i am giving my code here. Any criticism about the coding technique will be highly appreciated.

<?php

$time_zone = getTimeZoneFromIpAddress();
echo 'Your Time Zone is '.$time_zone;

function getTimeZoneFromIpAddress(){
    $clientsIpAddress = get_client_ip();

    $clientInformation = unserialize(file_get_contents('http://www.geoplugin.net/php.gp?ip='.$clientsIpAddress));

    $clientsLatitude = $clientInformation['geoplugin_latitude'];
    $clientsLongitude = $clientInformation['geoplugin_longitude'];
    $clientsCountryCode = $clientInformation['geoplugin_countryCode'];

    $timeZone = get_nearest_timezone($clientsLatitude, $clientsLongitude, $clientsCountryCode) ;

    return $timeZone;

}

function get_client_ip() {
    $ipaddress = '';
    if (getenv('HTTP_CLIENT_IP'))
        $ipaddress = getenv('HTTP_CLIENT_IP');
    else if(getenv('HTTP_X_FORWARDED_FOR'))
        $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
    else if(getenv('HTTP_X_FORWARDED'))
        $ipaddress = getenv('HTTP_X_FORWARDED');
    else if(getenv('HTTP_FORWARDED_FOR'))
        $ipaddress = getenv('HTTP_FORWARDED_FOR');
    else if(getenv('HTTP_FORWARDED'))
        $ipaddress = getenv('HTTP_FORWARDED');
    else if(getenv('REMOTE_ADDR'))
        $ipaddress = getenv('REMOTE_ADDR');
    else
        $ipaddress = 'UNKNOWN';
    return $ipaddress;
}

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 'unknown';
}
Possibly answered 2/9, 2015 at 13:41 Comment(0)
B
3

It's not straight forward but I get the time including daylight saving offset from 2 api calls using jquery and php. All of it could be done in PHP quite easily with a bit of adaptation. I'm sure this could be laid out differently too but I just grabbed it from existing code which suited my needs at the time.

Jquery/php:

function get_user_time(){
    var server_time = <? echo time(); ?>; //accuracy is not important it's just to let google know the time of year for daylight savings time
    $.ajax({
        url: "locate.php",
        dataType: "json",
        success: function(user_location) {
            if(user_location.statusCode=="OK"){
                $.ajax({
                    url: "https://maps.googleapis.com/maps/api/timezone/json?location="+user_location.latitude+","+user_location.longitude+"&timestamp="+server_time+"&sensor=false",
                    dataType: "json",
                    success: function(user_time) {
                        if(user_time.statusCode=="error"){
                            //handle error
                        }else{
                            user_time.rawOffset /= 3600;
                            user_time.dstOffset /= 3600;
                            user_real_offset = user_time.rawOffset+user_time.dstOffset+user_time.utc;
                            //do something with user_real_offset
                        }
                    }
                });
            }
        }
    });
}

locate.php

function get_client_ip() {
    $ipaddress = '';
    if ($_SERVER['HTTP_CLIENT_IP'])
        $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
    else if($_SERVER['HTTP_X_FORWARDED_FOR'])
        $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
    else if($_SERVER['HTTP_X_FORWARDED'])
        $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
    else if($_SERVER['HTTP_FORWARDED_FOR'])
        $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
    else if($_SERVER['HTTP_FORWARDED'])
        $ipaddress = $_SERVER['HTTP_FORWARDED'];
    else if($_SERVER['REMOTE_ADDR'])
        $ipaddress = $_SERVER['REMOTE_ADDR'];
    else
        $ipaddress = 'UNKNOWN';

    return $ipaddress;
}
$location = file_get_contents('http://api.ipinfodb.com/v3/ip-city/?key=xxxxxxxxx&ip='.get_client_ip().'&format=json');
$location = json_decode($location,true);
if(is_array($location)){
    date_default_timezone_set('UTC');
    $location['utc'] = time();
    echo json_encode($location);
}else{
    echo '{"statusCode":"error"}';
}

Register for a free key here: http://ipinfodb.com/register.php (no limits but queued if more than 1 request per second)

Bixler answered 19/9, 2013 at 1:9 Comment(0)
D
2

If what you need to know is the timezone of users browsing your webpage, then you can use some service like IP2LOCATION to guess the timezone. Keep in mind though, as altCognito said, this is not a 100% accurate way of telling client's timezone. There are some accuracy problems with this approach.

Disabled answered 13/4, 2009 at 10:54 Comment(0)
I
2

Check out the Maxmind GeoLite2 database. It contains details about the continent/country/city and lat/lon for most IP addresses including the time_zone as you can see below.

I describe how to compile the PHP extension, and how to use the mmdb databases in PHP here:

Intro to Maxmind GeoLite2 with Kohana PHP

enter image description here

Impediment answered 10/3, 2014 at 21:53 Comment(0)
C
2

Here's an example using a location API that maps IP address to timezone, e.g. send a request to https://ipapi.co/<IP-Address>/timezone/ & get back timezone for that IP address.

PHP Code

file_get_contents('https://ipapi.co/1.2.3.4/timezone/');

Accuracy is not 100% as others have said.

Corroborant answered 20/3, 2017 at 13:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.