Determinar Fuso Horário do Usuário

votos
539

Existe alguma maneira padrão para um servidor Web para ser capaz de determinar fuso horário de um usuário dentro de uma página web?

Talvez a partir de um cabeçalho HTTP ou parte da string user-agent?

Publicado 01/08/2008 em 00:42
fonte usuário
Em outras línguas...                            


25 respostas

votos
302
-new Date().getTimezoneOffset()/60;

O método getTimezoneOffset()irá subtrair o seu tempo de GMT e retornar o número de minutos. Então, se você vive em GMT-8, ele retornará 480.

Para colocar isto em horas, divida por 60. Além disso, observe que o sinal é o oposto do que você precisa - é o cálculo do GMT do seu fuso horário, não o seu fuso horário com relação ao GMT. Para corrigir isso, basta multiplicar por -1.

Observe também que w3school diz:

O valor retornado não é uma constante, por causa da prática de usar horário de verão.

Respondeu 27/11/2009 em 18:52
fonte usuário

votos
174

O (== padrão?) Mais popular forma de determinar o fuso horário que eu vi em torno é simplesmente pedindo os próprios usuários. Se seu site requer assinatura, isso poderia ser salvos em dados do perfil dos usuários. Para usuários anon, as datas podem ser exibidos como UTC ou GMT ou algo assim.

Eu não estou tentando ser um espertinho. É que, por vezes, alguns problemas têm soluções mais finos fora de qualquer contexto de programação.

Respondeu 03/08/2008 em 20:30
fonte usuário

votos
77

Não há cabeçalhos HTTP que irá relatar o fuso horário clientes até agora, embora tenha sido sugerido para incluí-lo na especificação HTTP.

Se fosse comigo, eu provavelmente tentar buscar o fuso horário utilizando clientside JavaScript e, em seguida, enviá-lo para o servidor usando Ajax ou algo assim.

Respondeu 01/08/2008 em 13:19
fonte usuário

votos
47

Javascript é a maneira mais fácil de obter hora local do cliente. Gostaria de sugerir o uso de um XMLHttpRequestpara enviar de volta o tempo local, e se isso falhar, cair de volta para o fuso horário detectado com base no seu endereço IP.

Tanto quanto de geolocalização, eu usei MaxMind GeoIP em vários projetos e funciona bem, embora eu não tenho certeza se eles fornecem os dados de fuso horário. É um serviço que você paga e eles fornecem atualizações mensais para seu banco de dados. Eles fornecem wrappers em várias linguagens web.

Respondeu 01/08/2008 em 16:11
fonte usuário

votos
39

Aqui está uma solução JavaScript robusta para determinar a zona vez que o navegador está em.

>>> var timezone = jstz.determine();
>>> timezone.name(); 
"Europe/London"

https://bitbucket.org/pellepim/jstimezonedetect

Respondeu 06/08/2012 em 22:22
fonte usuário

votos
34

Aqui está uma maneira mais completa.

  1. Se o deslocamento de fuso horário para o usuário
  2. Testar alguns dias no DLS limites para determinar se eles estão em uma zona que utiliza DLS.

Exceto Abaixo:

function TimezoneDetect(){
    var dtDate = new Date('1/1/' + (new Date()).getUTCFullYear());
    var intOffset = 10000; //set initial offset high so it is adjusted on the first attempt
    var intMonth;
    var intHoursUtc;
    var intHours;
    var intDaysMultiplyBy;

    //go through each month to find the lowest offset to account for DST
    for (intMonth=0;intMonth < 12;intMonth++){
        //go to the next month
        dtDate.setUTCMonth(dtDate.getUTCMonth() + 1);

        //To ignore daylight saving time look for the lowest offset.
        //Since, during DST, the clock moves forward, it'll be a bigger number.
        if (intOffset > (dtDate.getTimezoneOffset() * (-1))){
            intOffset = (dtDate.getTimezoneOffset() * (-1));
        }
    }

    return intOffset;
}

Obtendo TZ e DST de JS (via Way Back Machine)

Respondeu 30/03/2011 em 21:48
fonte usuário

votos
26

Usando a abordagem de Unkwntech, eu escrevi uma função usando jQuery e PHP. Esta é testado e funciona!

Na página PHP onde você está quer ter o fuso horário como uma variável, tem esse trecho de código em algum lugar perto do topo da página:

<?php    
    session_start();
    $timezone = $_SESSION['time'];
?>

Isto irá ler a variável de sessão "tempo", que estamos agora prestes a criar.

Na mesma página, no, é preciso antes de tudo incluem jQuery:

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>

Também no, abaixo do jQuery, cole o seguinte:

<script type="text/javascript">
    $(document).ready(function() {
        if("<?php echo $timezone; ?>".length==0){
            var visitortime = new Date();
            var visitortimezone = "GMT " + -visitortime.getTimezoneOffset()/60;
            $.ajax({
                type: "GET",
                url: "http://domain.com/timezone.php",
                data: 'time='+ visitortimezone,
                success: function(){
                    location.reload();
                }
            });
        }
    });
</script>

Você pode ou não ter notado, mas você precisa mudar a URL para o seu domínio real.

Uma última coisa. Você provavelmente está se perguntando o que o timezone.php diabos é. Bem, é simplesmente esta: (criar um novo arquivo chamado timezone.php e apontar para ele com o url acima)

<?php
    session_start();
    $_SESSION['time'] = $_GET['time'];
?>

Se isso funcionar corretamente, ele irá primeiro carregar a página, executar o JavaScript e recarregue a página. Então você vai ser capaz de ler a variável de fuso horário $ e usá-lo para o seu prazer! Ele retorna o deslocamento zona actual UTC / GMT tempo (GMT -7) ou qualquer fuso horário em que está.

Respondeu 09/04/2011 em 20:16
fonte usuário

votos
18

Em primeiro lugar, entender que a detecção de fuso horário em JavaScript é imperfeito. Você pode obter o local de deslocamento de fuso horário uma determinada data e hora usando para getTimezoneOffsetem uma instância do Dateobjeto, mas isso não é bem o mesmo que um completo fuso horário IANA como America/Los_Angeles.

Existem algumas opções que podem trabalhar no entanto:

  • A maioria dos navegadores modernos suportam fusos horários IANA na sua implementação da API ECMAScript Internacionalização , para que você pode fazer isso:

    const tzid = Intl.DateTimeFormat().resolvedOptions().timeZone;
    

    O resultado é uma string contendo a definição de fuso horário IANA do computador onde o código está sendo executado.

    Ambientes suportados estão listados na tabela de compatibilidade Intl . Expanda a DateTimeFormatseção, e olhar para o recurso chamado resolvedOptions().timeZone defaults to the host environment.

  • Se você precisa para apoiar um conjunto mais amplo de ambientes, tais como navegadores mais antigos, você pode usar uma biblioteca para fazer um palpite no fuso horário. Eles trabalham por primeiro tentar o IntlAPI se estiver disponível, e quando ele não está disponível, eles interrogar a getTimezoneOffsetfunção doDate objeto, por vários pontos diferentes no tempo, usando os resultados para escolher um fuso horário apropriado a partir de um conjunto de dados interno.

    Ambos jsTimezoneDetect e momento-fuso horário tem esta funcionalidade.

    // using jsTimeZoneDetect
    var tzid = jstz.determine().name();
    
    // using moment-timezone
    var tzid = moment.tz.guess();
    

    Em ambos os casos, o resultado só pode ser pensado como um palpite. A suposição pode estar correto em muitos casos, mas não todos eles.

    Além disso, essas bibliotecas têm de ser atualizado periodicamente para compensar o fato de que muitas implementações de JavaScript mais velhos são apenas conscientes da atual horário de verão regra tempo para o seu fuso horário local. Mais detalhes sobre isso aqui.

Em última análise, a melhor abordagem é, na verdade, pergunte ao seu usuário para o seu fuso horário. Proporcionar um ambiente que eles podem mudar. Você pode usar uma das opções acima para escolher um padrão configuração, mas não torná-lo impossível desviar-se que em seu aplicativo.

Há também o totalmente diferente abordagem de não contar com a configuração de fuso horário do computador do usuário em tudo. Em vez disso, se você pode reunir latitude e longitude, você pode resolver os para um fuso horário usando um destes métodos . Isso funciona bem em dispositivos móveis.

Respondeu 25/03/2014 em 04:47
fonte usuário

votos
18

Para submeter o deslocamento como um cabeçalho HTTP em solicitações de AJAX com fuso horário jQuery

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        xhr.setRequestHeader("X-TZ-Offset", -new Date().getTimezoneOffset()/60);
    }
});

Você também pode fazer algo semelhante para obter o nome real fuso horário utilizando moment.tz.guess();a partir http://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/

Respondeu 13/09/2012 em 03:05
fonte usuário

votos
18

Eu ainda não vi uma resposta detalhada aqui que começa o fuso horário. Você não deve precisar geocodificar por endereço IP ou usar o PHP (lol) ou incorretamente acho que a partir de um deslocamento.

Em primeiro lugar um fuso horário não é apenas um deslocamento de GMT. É uma área de terra em que as regras relativas ao tempo são definidas por normas locais. Alguns países têm horário de verão, e vai ligar DST em momentos diferentes. Geralmente é importante para obter a zona real, não apenas a corrente de deslocamento.

Se você pretende armazenar esse fuso horário, por exemplo, as preferências do usuário que você quer da zona e não apenas o deslocamento. Para conversões em tempo real não importa muito.

Agora, para obter o fuso horário com javascript você pode usar este:

>> new Date().toTimeString();
"15:46:04 GMT+1200 (New Zealand Standard Time)"
//Use some regular expression to extract the time.

No entanto, eu achei mais fácil simplesmente usar este plugin robusta que retorna o fuso horário formatado Olsen:

https://github.com/scottwater/jquery.detect_timezone

Respondeu 30/08/2012 em 06:08
fonte usuário

votos
16

Fácil, basta usar o JavaScript getTimezoneOffsetfunção assim:

-new Date().getTimezoneOffset()/60;
Respondeu 27/05/2012 em 18:25
fonte usuário

votos
16

Com função de data PHP você terá a data e hora de servidor no qual site está localizado. A única maneira de obter tempo do usuário é usar JavaScript.

Mas eu sugiro que você, se o seu site tiver necessidade de registro então melhor maneira é pedir usuário enquanto o registro como campo obrigatório. Você pode listar vários fusos horários no registro da página e salvar isso em banco de dados. Após isso, se o login do usuário para o site, então você pode definir o fuso horário padrão para essa sessão como por fuso horário selecionado de usuários. Você pode definir qualquer fuso horário específico usando a função PHP date_default_timezone_set. Este definir o fuso horário especificado para os usuários.

Basicamente fuso horário dos usuários é vai para o lado do cliente, por isso devemos usar JavaScript para isso.

Abaixo está o script para obter o fuso horário dos usuários utilizando PHP e JavaScript.

<?php
#http://www.php.net/manual/en/timezones.php List of Time Zones
function showclienttime()
{
  if(!isset($_COOKIE['GMT_bias']))
  {
    ?>
    <script type="text/javascript">
    var Cookies = {};
    Cookies.create = function (name, value, days) {
      if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        var expires = "; expires=" + date.toGMTString();
      } else {
        var expires = "";
      }
      document.cookie = name + "=" + value + expires + "; path=/";
      this[name] = value;
    }

    var now = new Date();
    Cookies.create("GMT_bias",now.getTimezoneOffset(),1);
    window.location = "<?php echo $_SERVER['PHP_SELF'];?>";
    </script>
    <?php
  } else {
    $fct_clientbias = $_COOKIE['GMT_bias'];
  }

  $fct_servertimedata = gettimeofday();
  $fct_servertime = $fct_servertimedata['sec'];
  $fct_serverbias = $fct_servertimedata['minuteswest'];
  $fct_totalbias = $fct_serverbias – $fct_clientbias;
  $fct_totalbias = $fct_totalbias * 60;
  $fct_clienttimestamp = $fct_servertime + $fct_totalbias;
  $fct_time = time();
  $fct_year = strftime("%Y", $fct_clienttimestamp);
  $fct_month = strftime("%B", $fct_clienttimestamp);
  $fct_day = strftime("%d", $fct_clienttimestamp);
  $fct_hour = strftime("%I", $fct_clienttimestamp);
  $fct_minute = strftime("%M", $fct_clienttimestamp);
  $fct_second = strftime("%S", $fct_clienttimestamp);
  $fct_am_pm = strftime("%p", $fct_clienttimestamp);
  echo $fct_day.", ".$fct_month." ".$fct_year." ( ".$fct_hour.":".$fct_minute.":".$fct_second." ".$fct_am_pm." )";
}

showclienttime();
?>

Mas de acordo com meu ponto de vista, é melhor perguntar aos usuários se o registro é obrigatório em seu projeto.

Respondeu 16/09/2010 em 06:59
fonte usuário

votos
16

Alguém sabe de quaisquer serviços que irá corresponder IP para localização geográfica

Bem, sorte para você que resposta pode ser encontrada em nosso próprio site stackoverflow: Como obter o País de acordo com um determinado IP?

Spoiler: http://www.hostip.info/use.html

Respondeu 04/08/2008 em 12:11
fonte usuário

votos
15

javascript:

function maketimus(timestampz)
{
    var linktime = new Date(timestampz * 1000);
    var linkday = linktime.getDate();
    var freakingmonths=new Array();

    freakingmonths[0]="jan";
    freakingmonths[1]="feb";
    freakingmonths[2]="mar";
    freakingmonths[3]="apr";
    freakingmonths[4]="may";
    freakingmonths[5]="jun";
    freakingmonths[6]="jul";
    freakingmonths[7]="aug";
    freakingmonths[8]="sep";
    freakingmonths[9]="oct";
    freakingmonths[10]="nov";
    freakingmonths[11]="dec";

    var linkmonthnum = linktime.getMonth();
    var linkmonth = freakingmonths[linkmonthnum];
    var linkyear = linktime.getFullYear();
    var linkhour = linktime.getHours();
    var linkminute = linktime.getMinutes();

    if (linkminute < 10)
    {
        linkminute = "0" + linkminute;
    }

    var fomratedtime = linkday + linkmonth + linkyear + " " + linkhour + ":" + linkminute + "h";
    return fomratedtime;
}    

simplesmente fornecer seus tempos em formato UNIX Timestamp para esta função, javascript já sabe o fuso horário do usuário.

como isso:

php:

echo '<script type="text/javascript">
var eltimio = maketimus('.$unix_timestamp_ofshiz.');
document.write(eltimio);
</script><noscript>pls enable javascript</noscript>';

este será sempre mostrar os tempos corretamente com base no fuso horário da pessoa estabeleceu em seu relógio do computador, não há necessidade de pedir nada a ninguém e guardá-lo em lugares graças a Deus!

Respondeu 28/08/2011 em 00:00
fonte usuário

votos
14

Não use o endereço IP para determinar definitivamente localização (e fuso horário hense) - que é porque com NAT, proxies (cada vez mais popular), e VPNs, endereços IP não necessariamente de forma realista refletir localização real do usuário, mas o local em que os servidores execução desses protocolos residem.

Semelhante à forma como códigos de área não é mais útil para localizar um usuário de telefone são, dada a popularidade da Portabilidade Numérica.

IP e outras técnicas mostradas acima são úteis para o que sugere um padrão que o utilizador pode ajustar / correcta.

Respondeu 02/01/2013 em 19:05
fonte usuário

votos
14

A magia tudo parece estar em

visitortime.getTimezoneOffset()

Isso é legal, eu não sei sobre isso. Será que funciona no IE, etc? De lá, você deve ser capaz de usar JS para o Ajax, definir cookies, qualquer que seja. Eu provavelmente ir a rota do bolinho mim.

Você precisa permitir que o usuário alterá-lo embora. Tentamos usar geolocalização (via MaxMind) para fazer isso um tempo atrás, e é errado era razoavelmente muitas vezes - o suficiente para torná-lo não vale a pena fazer, então apenas permitir que o usuário colocá-lo em seu perfil, e mostrar um aviso aos usuários que não definiu deles ainda.

Respondeu 03/08/2008 em 21:40
fonte usuário

votos
11

Uma maneira simples de fazer isso é usando:

new Date().getTimezoneOffset();
Respondeu 01/12/2011 em 12:08
fonte usuário

votos
11

Se acontecer de você estar usando OpenID para autenticação, Extensão de Registro simples resolveria o problema para usuários autenticados (Você precisa converter de tz para numérico).

Outra opção seria a de inferir o fuso horário de preferência o país do agente do usuário. Este é um método pouco em bruto (não irá funcionar para en-US), mas faz uma boa aproximação.

Respondeu 30/08/2008 em 10:29
fonte usuário

votos
10

Aqui está um artigo (com código fonte) que explica como determinar e usar o tempo localizada em uma (, C # VB.NET) aplicação ASP.NET:

Já estava na hora

Em suma, a abordagem descrita depende do JavaScript getTimezoneOffsetfunção, que retorna o valor que é salvo no cookie de sessão e utilizado por code-behind para ajustar os valores de tempo entre a GMT ea hora local. O bom é que o usuário não precisa especificar o fuso horário (o código faz isso automaticamente). Há mais envolvido (é por isso que eu link para o artigo), mas código fornecido torna realmente fácil de usar. Eu suspeito que você pode converter a lógica para PHP e outras linguagens (contanto que você entenda ASP.NET).

Respondeu 25/05/2010 em 01:11
fonte usuário

votos
8

Simples com JSe PHP:

Mesmo que o usuário pode mexer com o seu relógio interno e / ou fuso horário, a melhor maneira que eu encontrei até agora, para obter o deslocamento, permanece new Date().getTimezoneOffset();. Sua não-invasivo, não dá cabeça-dores e elimina a necessidade de recorrer a terceiros.

Digamos que eu tenha uma tabela usersque contém um campo date_created int(13), para armazenar timestamps UNIX;

Assumindo um cliente creates a new account, os dados são recebidos por post, e eu preciso insert/updateo date_created columncom timestamp unix do cliente, não o servidor do.

Desde o timezoneOffset é necessária no momento da insert / update, ele é passado como um elemento $ _POST extra quando o cliente envia o formulário, eliminando assim a necessidade de armazená-lo em sessões e / ou cookies, e nenhum servidor adicional atinge qualquer um.

var off = (-new Date().getTimezoneOffset()/60).toString();//note the '-' in front which makes it return positive for negative offsets and negative for positive offsets
var tzo = off == '0' ? 'GMT' : off.indexOf('-') > -1 ? 'GMT'+off : 'GMT+'+off;

Digamos que o servidor recebe tzocomo $_POST['tzo'];

$ts = new DateTime('now', new DateTimeZone($_POST['tzo']);
$user_time = $ts->format("F j, Y, g:i a");//will return the users current time in readable format, regardless of whether date_default_timezone() is set or not.
$user_timestamp = strtotime($user_time);

Inserir / atualizar date_created=$user_timestamp.

Ao recuperar o date_created, você pode converter o timestamp assim:

$date_created = //get from db
$created = date("F j, Y, g:i a",$date_created);//return it to the user or whatever

Agora, este exemplo pode caber nossas necessidades, quando se trata de inserir um firsttimestamp ... Quando se trata de um timestamp adicional, ou tabela, u pode querer considerar inserir o valor TZO na tabela de usuários para referência futura, ou defini-lo como sessão ou como um cookie.

PS mas que se o usuário viaja e alterna fusos horários. Entra em GMT + 4, viaja rápido para GMT-1 e os registros novamente. Último login seria no futuro.

Eu acho ... que pensar muito.

Respondeu 15/09/2014 em 02:19
fonte usuário

votos
7

Tente este código php

<?php  
$ip = $_SERVER['REMOTE_ADDR'];
$json = file_get_contents("http://api.easyjquery.com/ips/?ip=".$ip."&full=true");
$json = json_decode($json,true);
$timezone = $json['LocalTimeZone'];
?>
Respondeu 30/07/2012 em 09:08
fonte usuário

votos
7

Aqui está como eu faço isso. Isto irá definir o fuso horário PHP padrão de fuso horário local do usuário. Basta colar o seguinte no topo de todas as suas páginas:

<?php
session_start();

if(!isset($_SESSION['timezone']))
{
    if(!isset($_REQUEST['offset']))
    {
    ?>
        <script>
        var d = new Date()
        var offset= -d.getTimezoneOffset()/60;
        location.href = "<?php echo $_SERVER['PHP_SELF']; ?>?offset="+offset;
        </script>
        <?php   
    }
    else
    {
        $zonelist = array('Kwajalein' => -12.00, 'Pacific/Midway' => -11.00, 'Pacific/Honolulu' => -10.00, 'America/Anchorage' => -9.00, 'America/Los_Angeles' => -8.00, 'America/Denver' => -7.00, 'America/Tegucigalpa' => -6.00, 'America/New_York' => -5.00, 'America/Caracas' => -4.30, 'America/Halifax' => -4.00, 'America/St_Johns' => -3.30, 'America/Argentina/Buenos_Aires' => -3.00, 'America/Sao_Paulo' => -3.00, 'Atlantic/South_Georgia' => -2.00, 'Atlantic/Azores' => -1.00, 'Europe/Dublin' => 0, 'Europe/Belgrade' => 1.00, 'Europe/Minsk' => 2.00, 'Asia/Kuwait' => 3.00, 'Asia/Tehran' => 3.30, 'Asia/Muscat' => 4.00, 'Asia/Yekaterinburg' => 5.00, 'Asia/Kolkata' => 5.30, 'Asia/Katmandu' => 5.45, 'Asia/Dhaka' => 6.00, 'Asia/Rangoon' => 6.30, 'Asia/Krasnoyarsk' => 7.00, 'Asia/Brunei' => 8.00, 'Asia/Seoul' => 9.00, 'Australia/Darwin' => 9.30, 'Australia/Canberra' => 10.00, 'Asia/Magadan' => 11.00, 'Pacific/Fiji' => 12.00, 'Pacific/Tongatapu' => 13.00);
        $index = array_keys($zonelist, $_REQUEST['offset']);
        $_SESSION['timezone'] = $index[0];
    }
}

date_default_timezone_set($_SESSION['timezone']);

//rest of your code goes here
?>
Respondeu 28/01/2012 em 09:21
fonte usuário

votos
6

Uma opção possível é usar o Datecampo de cabeçalho, que é definido na RFC 7231 e é suposto para incluir o fuso horário. Claro, não é garantido que o valor é realmente fuso horário do cliente, mas pode ser um ponto de partida conveniente.

Respondeu 09/09/2014 em 00:25
fonte usuário

votos
5

Conseguir um nome de fuso horário banco de dados TZ válido em PHP é um processo de duas etapas:

1) Com Javascript, se deslocamento de fuso horário em minutos através getTimezoneOffset. Esse deslocamento será positivo se o fuso horário local é atrás de UTC e negativo se está à frente. Portanto, você deve adicionar um sinal oposto ao offset.

var timezone_offset_minutes = new Date().getTimezoneOffset();
timezone_offset_minutes = timezone_offset_minutes == 0 ? 0 : -timezone_offset_minutes;

Passe este deslocamento para PHP.

2) Em PHP converter este deslocamento em um nome de fuso horário válido com timezone_name_from_abbr função.

// Just an example.
$timezone_offset_minutes = -360;  // $_GET['timezone_offset_minutes']

// Convert minutes to seconds
$timezone_name = timezone_name_from_abbr("", $timezone_offset_minutes*60, false);

// America/Chicago
echo $timezone_name;

Eu escrevi um post sobre ele: http://usefulangle.com/post/31/detect-user-browser-timezone-name-in-php Ele contém uma demo também.

Respondeu 10/01/2017 em 11:56
fonte usuário

votos
5

você poderia fazê-lo em cliente com momento-fuso horário e enviar o valor para servidor; uso de amostra:

> moment.tz.guess()
"America/Asuncion"
Respondeu 13/09/2016 em 06:19
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more