2008-08-01 21 views
519

¿Hay alguna manera estándar para que un servidor web pueda determinar la zona horaria de un usuario dentro de una página web? ¿Tal vez desde un encabezado HTTP o parte de la cadena de agente de usuario?Determinar la zona horaria de un usuario

+21

Considere la posibilidad de hacer de John Isaacks la respuesta correcta ... Su solución es mucho más simple, por decirlo suavemente. – catphive

+4

Pregunta al usuario. Si obtiene la zona horaria de la computadora del usuario, y está configurada incorrectamente, ¿entonces qué? –

+19

¿Entonces el usuario probablemente no le importe? – agnoster

Respuesta

73

No hay encabezados HTTP que informarán la zona horaria de los clientes hasta el momento, aunque se ha sugerido su inclusión en la especificación HTTP.

Si fuera yo, probablemente trataría de buscar la zona horaria usando JavaScript del lado del cliente y luego enviarla al servidor usando Ajax o algo así.

+4

Extrañamente, esta es la única respuesta ** correcta ** a la pregunta, que pregunta cómo hacerlo desde el lado del servidor. Sospecho que la razón por la que hay otras respuestas con más votos es porque una vez que te das cuenta de que tienes que hacerlo desde el lado del cliente, terminas usando las otras respuestas. Pero en mi humilde opinión, cualquier persona que haya votado en favor de otra respuesta también debe votar esta vez. – TTT

+0

Creo que el mejor método es utilizar la ubicación de geo-ip para ordenar las zonas horarias posibles y seleccionar de manera predeterminada la primera que coincida (cercana) con el desfase temporal del agente de usuario (se requiere JavaScript). Incluso después de eso, debe proporcionar una forma de arreglar la zona horaria incluso después de que este método seleccione el incorrecto. –

+0

@MikkoRantalainen tener cuidado al usar proxys, ya que no siempre se anuncian en los encabezados. – Matthieu

46

Javascript es la forma más fácil de obtener la hora local del cliente. Sugiero usar un XMLHttpRequest para devolver la hora local, y si eso falla, retroceda a la zona horaria detectada en función de su dirección IP.

En cuanto a la geolocalización, he usado MaxMind GeoIP en varios proyectos y funciona bien, aunque no estoy seguro de si proporcionan datos de zona horaria. Es un servicio que paga y proporciona actualizaciones mensuales para su base de datos. Proporcionan envoltorios en varios idiomas web.

+0

He votado esta respuesta debido a la latitud y longitud obtenida de bases de datos como GeoIP (que tiene una versión gratuita disponible a partir de ahora) se puede combinar con bases de datos que convierten dicha coordenada en una zona horaria. Creo que GeoNames tiene una última base de datos. –

+0

Véase también [esta pregunta] (http://stackoverflow.com/questions/5584602). –

+0

Las versiones actuales (tanto gratuitas como de pago) de las bases de datos/API de MaxMind GeoIP, sí proporcionan información de zona horaria (devuelve "Europa/Londres" para mi zona horaria). No recuerdo si la versión anterior de su GeoIP sistema hizo lo mismo, pero funciona muy bien ahora! Los campos de MaxMind se llaman "time_zone", "time_zone_name". –

173

La forma más popular (== estándar?) De determinar la zona horaria que he visto es simplemente preguntando a los usuarios. Si su sitio web requiere suscripción, esto podría guardarse en los datos del perfil de los usuarios. Para los usuarios de anon, las fechas se pueden mostrar como UTC o GMT o algo así.

No estoy tratando de ser inteligente. Es solo que a veces algunos problemas tienen soluciones más finas fuera de cualquier contexto de programación.

+3

¿Qué ocurre cuando un usuario está descargando un archivo .ics que debe tener una hora de inicio específica para su ubicación (por ejemplo, de 9 a 11 a.m. en todo el país)? No deberían TENER que decir cuál es su zona horaria. –

+0

¿Por qué no aceptar esto como la respuesta correcta? La respuesta dada por Unkwntech incluso no funciona para navegadores que no sean IE. –

+19

@Ishmaeel: pero los usuarios viajan internacionalmente y no deberían precisar su zona horaria cada vez que inician sesión desde una zona horaria no nativa –

14

La magia todo parece estar en

visitortime.getTimezoneOffset() 

Eso está bien, yo no sé nada de eso. Funciona en IE, etc.? Desde allí, debería poder usar JS para ajax, establecer cookies, lo que sea. Probablemente yo mismo iré a la ruta de las galletas.

No obstante, deberá permitir que el usuario lo cambie. Intentamos utilizar la geolocalización (a través de maxmind) para hacer esto hace un tiempo, y fue un error razonablemente a menudo, lo suficiente para que no valga la pena hacerlo, por lo que solo permitimos que el usuario lo establezca en su perfil y muestre un aviso a los usuarios que no han establecido el suyo todavía

16

Alguien sabe de cualquier servicio que se partido de IP a la ubicación geográfica

Bueno, por suerte para que esa respuesta se puede encontrar en nuestro propio sitio web StackOverflow: How to get the Country according to a certain IP?

alerón: http://www.hostip.info/use.html

+0

Acabo de ir a ese sitio web y estaba totalmente equivocado: -/ –

+0

@AdamLassek: posiblemente información interesante, pero ¿puede explicar por qué? –

+0

@ AndréCaron Dice que estoy en Irvine, California, cuando en realidad estoy en Omaha, NE. –

11

Si está usando OpenID para la autenticación, Simple Registration Extension solía ve el problema para usuarios autenticados (necesitarás convertir de tz a numérico).

Otra opción sería inferir la zona horaria de la preferencia de país del agente de usuario. Este es un método algo crudo (no funcionará en en-US), pero hace una buena aproximación.

298
-new Date().getTimezoneOffset()/60; 

getTimezoneOffset() restará su tiempo a la hora GMT y devolver el número de minutos. Entonces, si vives en GMT-8, devolverá 480.Para poner esto en horas, divida por 60. Además, observe que el signo es lo contrario de lo que necesita: calcula el desplazamiento de GMT desde su zona horaria, no el desplazamiento de la zona horaria desde GMT. Para solucionar esto, simplemente multiplique por -1.

Editar

También tenga en cuenta que w3school dice:

El valor devuelto no es una constante, debido a la práctica de utilizar horario de verano.

+1

esto es lo que tiene más sentido para mí. ¿Hay alguna razón para que esto no se use o todo el mundo está por encima de hacer que el problema sea más difícil de lo necesario? – jordanstephens

+0

@jordanstephens No soy un experto, así que no sé si hay circunstancias en las que esto no funcionaría, pero me funcionó bien. –

+5

¿Qué pasa con los usuarios que usan teléfonos celulares que tienen navegadores sin soporte de JavaScript? Me gusta la pregunta, el usuario pregunta acerca de los encabezados HTTP, agente de usuario ... ¿hay alguna manera de hacer que este trabajo sea del lado del servidor, lo más preciso posible? – Nischal

10

Aquí es un artículo (con código fuente) que explica cómo determinar y utilizar el tiempo localizada en un (, VB.NET C#) aplicación ASP.NET:

It's About Time

En resumen, el enfoque descrito se basa en la función JavaScript getTimezoneOffset, que devuelve el valor que se guarda en la cookie de sesión y que utiliza code-behind para ajustar los valores de tiempo entre GMT y la hora local. Lo bueno es que el usuario no necesita especificar la zona horaria (el código lo hace automáticamente). Hay más involucrados (es por esto que me enlace al artículo), pero el código proporcionado lo hace realmente fácil de usar. Sospecho que puedes convertir la lógica a PHP y otros lenguajes (siempre que entiendas ASP.NET).

+1

El enlace está muerto. Creo que este es el enlace alternativo: http://www.devproconnections.com/article/aspnet2/it-s-about-time-122778 – Gan

+1

El artículo está disponible en formato PDF aquí también: https://app.box. com/shared/bfvvmidtyg –

+0

El método para convertir el tiempo del servidor UTC a la hora del cliente local descrito en este artículo es incorrecto. El uso del desplazamiento actual del cliente para ajustar las horas UTC en el servidor dará como resultado tiempos "locales" incorrectos para la mitad del año para las configuraciones regionales del cliente que observen el horario de verano. Considere este escenario: un cliente en el Reino Unido el 14 de enero de 2013 (hora estándar GMT + 0000) establece una fecha y hora del 21 de agosto de 2015 a las 14:00 (GMT + 0100 horario de verano). Esto se normaliza en el servidor hasta el 21 de agosto de 2015 13:00 UTC. En el día en que esto ocurre, el desplazamiento del cliente es 0, por lo que el tiempo devuelto al cliente será el 21 de agosto de 2015 a las 13:00. –

16

Con la función de fecha de PHP, obtendrá la fecha y hora del servidor en el que se encuentra el sitio. La única manera de obtener tiempo del usuario es usar JavaScript.

Pero le sugiero que, si su sitio tiene registro requerido, entonces la mejor manera es preguntar al usuario mientras se registra como campo obligatorio. Puede enumerar varias zonas horarias en la página de registro y guardarlas en la base de datos. Después de esto, si el usuario inicia sesión en el sitio, puede establecer la zona horaria predeterminada para esa sesión según el huso horario seleccionado por los usuarios. Puede configurar cualquier zona horaria específica con la función PHP date_default_timezone_set. Esto establece el huso horario especificado para los usuarios.

Básicamente, la zona horaria de los usuarios va al lado del cliente, por lo que debemos usar JavaScript para esto.

A continuación se muestra la secuencia de comandos para obtener la zona horaria de los usuarios utilizando PHP y 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(); 
?> 

Pero según mi punto de vista, es mejor preguntar a los usuarios si el registro es obligatorio en su proyecto.

33

Aquí hay una manera más completa.

  1. Obtener la zona horaria de compensación para el usuario
  2. prueba algunos días en los límites de DLS para determinar si se encuentran en una zona que utiliza DLS.

Excepto continuación:

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; 
} 

Getting TZ and DST from JS (a través Way Back Machine)

+0

¡Esto funcionó para mí! Lea los comentarios en la publicación del blog para obtener un par de actualizaciones del código. – arlomedia

+0

Esto solo devolverá el * offset * estándar para la zona horaria, como +02: 00. No le dará suficiente información para determinar la * zona horaria * del usuario, como 'África/Johannesburgo' o 'Europa/Estambul'. Ver [la wiki de la etiqueta de la zona horaria] (http://stackoverflow.com/tags/timezone/info). –

26

Utilizando el enfoque de Unkwntech, escribí una función utilizando jQuery y PHP. ¡Esto se prueba y funciona!

En la página PHP en el que se desea tener la zona horaria como una variable, tienen este fragmento de código en algún lugar cerca de la parte superior de la página:

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

Esto permitirá la lectura de la variable de sesión "tiempo", que ahora estamos a punto de crear

En la misma página, en el, es necesario en primer lugar incluir jQuery:

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

También en el, por debajo del jQuery, pega este:

<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> 

puede o no lo has notado, pero debes cambiar la URL a tu dominio real.

Una última cosa. Probablemente se esté preguntando qué diablos es timezone.php. Bueno, es simplemente esto: (crear un nuevo archivo llamado timezone.php y apuntan a que con la URL anterior)

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

Si esto funciona correctamente, primero se carga la página, ejecutar el código JavaScript y recarga la página ¡Entonces podrá leer la variable $ zonezone y usarla para su gusto! Devuelve el actual UTC/GMT desplazamiento de zona horaria (GMT -7) o cualquier zona horaria se encuentra en

+0

me gusta esto, pero podría tener algo que compruebe el $ _SESSION actual ['time'] y solo obtener el javascript para volver a cargar si es diferente –

+1

Probablemente sea más fácil usar una cookie que una sesión para transportar esto, ya que el bloqueo y deserializar la sesión de PHP puede causar ralentizaciones en su aplicación. Para obtener la máxima eficacia, puede copiar el valor en la sesión y eliminar la cookie para que no se envíe en las solicitudes posteriores. – IMSoP

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; 
}  

sólo tiene que proporcionar sus tiempos en formato de marca de tiempo Unix a esta función, ya se sabe Javascript la zona horaria del usuario.

así:

php:

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

esta siempre mostrará los tiempos correctamente sobre la base de la zona horaria que la persona ha puesto en su reloj de la computadora, sin necesidad de pedir nada a nadie y guárdelo en lugares gracias a dios!

+0

$ unix_timestamp_ofshiz? Aquí falta algo y no funciona del todo, aunque parece que podría ser una buena respuesta. –

11

Una forma sencilla de hacerlo es mediante el uso de:

new Date().getTimezoneOffset(); 
+5

¿Por qué volvió a publicar una respuesta idéntica (por John Isaacks) de hace 2 años: http://stackoverflow.com/a/1809974/836407? – chown

+0

Además, solo devuelve la compensación de la zona horaria * actual *, no la * zona horaria *. Ver [la wiki de la etiqueta de la zona horaria] (http://stackoverflow.com/tags/timezone/info). –

7

Así es como lo hago. Esto establecerá la zona horaria predeterminada de PHP en la zona horaria local del usuario. Sólo tienes que pegar lo siguiente en la parte superior de todas las 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 
?> 
+1

Esto no cuenta para los ajustes de "horario de verano": un usuario en Dublín coincidiría con su "Europa/Dublín" en invierno, pero "Europa/Belgrado" en verano. Si va a utilizar el desplazamiento actual, todo lo que razonablemente puede asumir es ese desplazamiento, no un identificador geográfico. – IMSoP

16

fácil, sólo tiene que utilizar la función de JavaScript getTimezoneOffset así:

-new Date().getTimezoneOffset()/60; 
+1

Esta es una función de Javascript, no una función de PHP. – cincodenada

+0

Además, solo devuelve la compensación de la zona horaria * actual *, no la * zona horaria *. Ver [la wiki de la etiqueta de la zona horaria] (http://stackoverflow.com/tags/timezone/info). –

7

probar 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']; 
?> 
+0

Parece que http://api.easyjquery.com/ ya no está disponible – GingerPlusPlus

37

Aquí es una solución robusta de JavaScript para determinar la zona horaria en la que se encuentra el navegador

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

https://bitbucket.org/pellepim/jstimezonedetect

+9

Se desaconsejan las respuestas de enlace único, porque si el enlace desaparece, la respuesta deja de ser útil; y porque sin seguir el enlace, los lectores no saben si da una buena respuesta. En este caso, podría aclarar que se trata de una biblioteca de terceros que adopta un enfoque basado en bases de datos para la identificación, y tal vez explique algunos de los principios de su funcionamiento. – IMSoP

+1

Esto! Este es el camino a seguir. Biblioteca simple, maneja el horario de verano correctamente. Otras respuestas están llenas de WTF y muchas no hacen DST. – Dirbaio

+1

Esta biblioteca es muy inteligente. Funciona mediante la consulta del desplazamiento actual a UTC, luego ajusta el tiempo del objeto JavaScript Date agregando o restando segundos hasta que se modifique el UTC. Con este método, esta biblioteca descubre muchos cambios suficientes en el horario de verano para identificar de manera única la zona horaria. Creo que la biblioteca podría tener un rendimiento aún mejor si hiciera una búsqueda binaria en lugar de una búsqueda lineal. El valor de retorno es una clave de información de la zona IANA (también conocida como la base de datos de la zona horaria de Olson). –

18

todavía no he visto una respuesta detallada aquí donde se pone el huso horario. No debería necesitar geocodificar por dirección IP o usar PHP (lol) o adivinar incorrectamente desde un desplazamiento.

En primer lugar, una zona horaria no es solo una compensación de GMT. Es un área de tierra en la cual las reglas de tiempo son establecidas por estándares locales. Algunos países tienen horario de verano y activarán el horario de verano en diferentes horarios. Por lo general, es importante obtener la zona real, no solo la compensación actual.

Si desea almacenar esta zona horaria, por ejemplo, en las preferencias del usuario, desea la zona y no solo el desplazamiento. Para las conversiones en tiempo real no importará mucho.

Ahora, para obtener la zona horaria con javascript puede utilizar esto:

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

Sin embargo, me pareció más fácil de usar, simplemente esta sólida plugin que devuelve el Olsen zona horaria formato:

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

18

Para enviar el desplazamiento de zona horaria como un encabezado HTTP en solicitudes AJAX con jQuery

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

También puede hacer algo similar para obtener el nombre real de zona horaria mediante el uso de moment.tz.guess();http://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/

+0

Esto solo devuelve la compensación de la zona horaria * actual * - no la * zona horaria *. Ver [la wiki de la etiqueta de la zona horaria] (http://stackoverflow.com/tags/timezone/info). –

+0

Editado para incluir información sobre cómo hacer lo mismo para el nombre de la zona horaria. – philfreo

14

No utilice la dirección IP para determinar definitivamente la ubicación (y hense zona horaria) - eso es porque con el NAT, proxies (cada vez popular) y VPN, las direcciones IP no necesariamente reflejan de manera realista la ubicación real del usuario, sino la ubicación en la que residen los servidores que implementan dichos protocolos.

Similar a cómo los Códigos de Área ya no son útiles para localizar a un usuario de teléfono, dada la popularidad de la Portabilidad Numérica.

IP y otras técnicas que se muestran arriba son útiles para sugiriendo un defecto que el usuario puede ajustar/correcto.

16

Primero, entienda que la detección de zona horaria en JavaScript es imperfecta. Puede obtener la compensación de zona horaria local para una fecha y hora particular utilizando getTimezoneOffset en una instancia del objeto Date, pero eso no es lo mismo que IANA time zone como America/Los_Angeles.

Hay algunas opciones que pueden funcionar sin embargo:

  • mayoría de los navegadores modernos soportan las zonas horarias IANA en la aplicación de la ECMAScript Internationalization API, por lo que se puede hacer esto:

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

    El resultado es una cadena que contiene la configuración de zona horaria IANA de la computadora donde se ejecuta el código.

    Los entornos compatibles se enumeran in the Intl compatibility table.Expanda la sección DateTimeFormat y mire la característica denominada resolvedOptions().timeZone defaults to the host environment.

  • Si necesita admitir un conjunto más amplio de entornos, como navegadores web anteriores, puede utilizar una biblioteca para hacer una conjetura educada en la zona horaria. Trabajan primero probando la API Intl si está disponible, y cuando no está disponible, interrogan a la función getTimezoneOffset del objeto Date, para varios puntos diferentes en el tiempo, usando los resultados para elegir una zona horaria apropiada de un conjunto de datos interno.

    Ambos jsTimezoneDetect y moment-timezone tienen esta funcionalidad.

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

    En ambos casos, el resultado solo puede considerarse como una conjetura. La suposición puede ser correcta en muchos casos, pero no en todos.

    Además, estas bibliotecas deben actualizarse periódicamente para contrarrestar el hecho de que muchas implementaciones anteriores de JavaScript solo conocen la actual regla de horario de verano local. More details on that here.

En última instancia, un enfoque mejor es preguntar en realidad el usuario por su zona horaria. Proporcione una configuración que puedan cambiar. Puede usar una de las opciones anteriores para elegir una configuración predeterminada de , pero no es imposible desviarse de eso en su aplicación.

También existe el enfoque completamente diferente de y no dependiendo de la configuración de zona horaria de la computadora del usuario. En cambio, si puede reunir las coordenadas de latitud y longitud, puede resolverlas en un huso horario usando one of these methods. Esto funciona bien en dispositivos móviles.

6

Una posible opción es utilizar el campo de encabezado Date, que se define en RFC 7231 y se supone que debe incluir la zona horaria. Por supuesto, no se garantiza que el valor sea realmente la zona horaria del cliente, pero puede ser un punto de partida conveniente.

+0

Desafortunadamente, ese encabezado parece estar diseñado principalmente para respuestas, no para solicitudes: "Un agente de usuario PUEDE enviar un campo de encabezado de fecha en una solicitud, aunque generalmente no lo hará a menos que se crea que transmite información útil al servidor". Acabo de comprobar y Firefox no lo envía. – IMSoP

8

simple con JS y PHP:

Aunque el lío lata usuario con su reloj interno y/o la zona horaria, la mejor forma que encontré hasta ahora, para conseguir el desplazamiento, sigue siendo new Date().getTimezoneOffset();. No es invasivo, no causa dolores de cabeza y elimina la necesidad de depender de terceros.

Supongo que tengo una tabla users que contiene un campo date_created int(13), para almacenar marcas de tiempo de Unix;

Suponiendo un cliente creates a new account, los datos son recibidos por post, y necesito insert/update la date_created column con marca de tiempo Unix del cliente, no el servidor de.

Dado que timezoneOffset es necesario en el momento de insertar/actualizar, se pasa como un elemento $ _POST adicional cuando el cliente envía el formulario, eliminando así la necesidad de almacenarlo en sesiones y/o cookies, y no adicional el servidor golpea cualquiera.

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; 

Diga el servidor recibe tzo como $_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); 

Insertar/actualizar date_created=$user_timestamp.

Al recuperar la date_created, puede convertir la marca de tiempo, así:

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

Ahora, este ejemplo puede adaptarse a las necesidades de uno, cuando se trata de insertar una marca de tiempo first ... Cuando se trata de un adicional marca de tiempo, o tabla, puede considerar insertar el valor tzo en la tabla de usuarios para referencia futura, o establecerlo como sesión o como una cookie.

P.S. PERO, ¿y si el usuario viaja y cambia de zona horaria? Inicia sesión en GMT + 4, viaja rápidamente a GMT-1 y vuelve a iniciar sesión. El último inicio de sesión sería en el futuro.

Creo ... pensamos demasiado.

5

puede hacerlo en el cliente con moment-timezone y enviar el valor al servidor; ejemplos de uso:

> moment.tz.guess() 
"America/Asuncion" 
+0

El nombre de la función dice todo sobre su precisión ;-) – Legends

5

Obtención de una base de datos de zona horaria TZ nombre válido en PHP es un proceso de dos pasos:

1) Con Javascript, obtener compensación en minutos a través getTimezoneOffset zona horaria. Este desplazamiento será positivo si la zona horaria local está detrás de UTC y negativa si está adelante. Por lo tanto, debe agregar un signo opuesto al desplazamiento.

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

Pase esta compensación a PHP.

2) En PHP convierta esta compensación en un nombre de zona horaria válida con función timezone_name_from_abbr.

// 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;

He escrito una entrada de blog en él: http://usefulangle.com/post/31/detect-user-browser-timezone-name-in-php Contiene una demostración también.

Cuestiones relacionadas