Obtener el desplazamiento de la zona horaria del cliente en JavaScript

616

¿Cómo puedo reunir la información de zona horaria del visitante? Necesito la zona horaria, así como las horas de compensación GMT.

Árvíztűrő tükörfúrógép
fuente
3
Estoy imaginando el mismo problema ahora. Aquí hay un enfoque interesante.
Tamás Pap
31
El título solicita la zona horaria, mientras que el texto solicita la compensación GMT. Estas son 2 cosas diferentes. Una zona horaria incluye información sobre el horario de verano, el desplazamiento utc no. Una zona horaria tiene un nombre y un historial, la compensación no. Se recomienda editar el título a "Obtención del desplazamiento de gmt del cliente en JS".
citykid
Necesito la zona horaria. La compensación GMT también sería útil.
DaveWalley
99
Las respuestas aquí se centran principalmente en el desplazamiento . Para la zona horaria, vea esta respuesta . Ver "Time Zone! = Offset" en el wiki de etiqueta de zona horaria .
Matt Johnson-Pint
77
Obtiene la zona horaria exacta utilizando este Intl.DateTimeFormat (). ResolveOptions (). TimeZone
Mangesh Mandavgane

Respuestas:

594

var offset = new Date().getTimezoneOffset();
console.log(offset);

El desplazamiento de zona horaria es la diferencia, en minutos, entre la hora UTC y la hora local. Tenga en cuenta que esto significa que el desplazamiento es positivo si la zona horaria local está detrás de UTC y negativo si está adelante. Por ejemplo, si su zona horaria es UTC + 10 (hora estándar del este de Australia), se devolverá -600. El horario de verano evita que este valor sea constante incluso para un entorno local determinado

Tenga en cuenta que no todas las zonas horarias están compensadas por horas completas: por ejemplo, Terranova es UTC menos 3h 30m (dejando el horario de verano fuera de la ecuación).

NickFitz
fuente
42
@abernier ¿La declaración sobre getTimezoneOffsetimprecisión está vigente? El artículo al que se refiere está fechado en junio de 2007 y no tiene detalles de cómo la función es inexacta. Y, de hecho, la biblioteca jsTimezoneDetectque apuntaste se usa getTimezoneOffsetsola.
Mike
55
@abernier Es un estándar desde ES 1, así que estoy seguro de que cualquier problema de implementación podría solucionarse ahora, es decir, es un artículo de 7 años.
LasagnaAndroid
49
var hrs = -(new Date().getTimezoneOffset() / 60) para compensar en las horas que generalmente se usan
Edwin Daniels
66
Parece que no considera el horario de verano
Shahdat
21
timezone! =utc offset
bendytree
484

Usar un desplazamiento para calcular la zona horaria es un enfoque incorrecto, y siempre encontrará problemas. Las zonas horarias y las reglas de horario de verano pueden cambiar en varias ocasiones durante un año, y es difícil mantenerse al día con los cambios.

Para obtener la zona horaria IANA del sistema en JavaScript, debe usar

console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)

A partir de septiembre de 2019, esto funciona en el 95% de los navegadores utilizados a nivel mundial .

Información de compatibilidad antigua

ecma-402 / 1.0 dice que timeZonepuede estar indefinido si no se proporciona al constructor. Sin embargo, el borrador futuro (3.0) solucionó ese problema al cambiar a la zona horaria predeterminada del sistema.

En esta versión de la API de internacionalización ECMAScript, la timeZonepropiedad permanecerá indefinida si no timeZonese proporcionó ninguna propiedad en el objeto de opciones proporcionado al Intl.DateTimeFormat constructor . Sin embargo, las aplicaciones no deben confiar en esto, ya que las versiones futuras pueden devolver un valor de cadena que identifica la zona horaria actual del entorno host.

en ecma-402 / 3.0, que todavía está en borrador, cambió a

En esta versión de la API de internacionalización ECMAScript 2015, la timeZonepropiedad será el nombre de la zona horaria predeterminada si no timeZonese proporcionó ninguna propiedad en el objeto de opciones proporcionado al Intl.DateTimeFormatconstructor. La versión anterior dejó la timeZonepropiedad indefinida en este caso.

Pawel Dubiel
fuente
17
Esta es la única respuesta para obtener la zona horaria, que algunos usuarios pueden necesitar en lugar del desplazamiento solamente. Entonces, como una actualización en 2016-09, Intl funciona en la mayoría de los navegadores modernos pero no en Safari. Para ese navegador, hay una alternativa de JavaScript razonablemente precisa aquí: pellepim.bitbucket.org/jstz
user2085368
66
Verificó que esto ahora parece funcionar en Safari. (Usando la versión 10.0)
BadPirate
2
Sería bueno si esto funcionara en todos los navegadores modernos. Sin embargo, IE11 y el último Firefox regresan indefinidos para la propiedad timeZone.
Haprog
77
He probado ahora con Chrome 58, Edge 40 y Firefox 53, funciona todos. No funciona con IE 11, no probé Opera.
Suma
8
Me llevó un tiempo encontrar la lista de zonas horarias que devuelve esta API. Aquí está: en.wikipedia.org/wiki/List_of_tz_database_time_zones
Xavier Poinas
123

Me doy cuenta de que esta respuesta está un poco fuera de tema, pero imagino que muchos de nosotros que buscamos una respuesta también queríamos formatear la zona horaria para mostrar y tal vez obtener la abreviatura de la zona también. Así que aquí va ...

Si desea que la zona horaria del cliente esté bien formateada, puede confiar en el método JavaScript Date.toString y hacer:

var split = new Date().toString().split(" ");
var timeZoneFormatted = split[split.length - 2] + " " + split[split.length - 1];

Esto le dará "GMT-0400 (EST)", por ejemplo, incluidos los minutos de la zona horaria cuando corresponda.

Alternativamente, con regex puede extraer cualquier parte deseada:

Para "GMT-0400 (EDT)":

new Date().toString().match(/([A-Z]+[\+-][0-9]+.*)/)[1]

Para "GMT-0400":

new Date().toString().match(/([A-Z]+[\+-][0-9]+)/)[1]

Por solo "EDT":

new Date().toString().match(/\(([A-Za-z\s].*)\)/)[1]

Por solo "-0400":

new Date().toString().match(/([-\+][0-9]+)\s/)[1]

Referencia de Date.toString: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/toString

Márquez
fuente
44
Roto con Chrome, ya que agrega el nombre de la zona horaria. No use split.length sino una constante en su lugar split[4] + " " + split[5].
Christophe Roussy
44
Esto tampoco funciona en (sorpresa, sorpresa) IE. Acabo de hacer un volcado de consola del objeto Fecha dividida. Es lo mismo en Chrome, Firefox y Safari, pero diferente en IE. Por lo tanto, tampoco puede contar con los índices constantes. Lun Dic 02 2013 10:22:50 GMT-0500 (EST): Chrome, FF, Safari; Lun 2 Dic 10:22:50 EST 2013: IE10
adimauro
1
Gosh gracias! He estado saltando por los aros tratando de mostrar la zona horaria del navegador ... ew Date (). ToString (). Match (/ ([AZ] + [\ + -] [0-9] +. *) /) [ 1] fue exactamente lo que necesitaba!
KiwiSunGoddess
1
Esto no funciona Para mí splitcontiene: ["Mon", "Mar", "13", "2017", "14:05:22", "GMT-0400", "(Eastern", "Daylight", "Time)"]así que el resultado esDaylight Time)
DLeh
77
En realidad, esto no es una buena idea, la representación real del tiempo de JS después de hacerlo new Date().toString()depende completamente de la configuración regional. Esperar que los resultados de otros clientes se parezcan a los suyos es una muy mala idea.
Octopus
71

Ya se ha respondido cómo obtener el desplazamiento en minutos como un entero, pero en caso de que alguien quiera el desplazamiento GMT local como una cadena, por ejemplo "+1130":

function pad(number, length){
    var str = "" + number
    while (str.length < length) {
        str = '0'+str
    }
    return str
}

var offset = new Date().getTimezoneOffset()
offset = ((offset<0? '+':'-')+ // Note the reversed sign!
          pad(parseInt(Math.abs(offset/60)), 2)+
          pad(Math.abs(offset%60), 2))
crio
fuente
1
pad(parseInt(Math.abs(offset/60)), 2)Debe reemplazar el primer relleno con para hacerlo bien ... de lo contrario, podría terminar obteniendo +5,530 como en mi caso ... no estoy seguro de si el piso de matemáticas, etc., será algo mejor aquí o no ... pero esto al menos me da +0530 como se esperaba
Abhinav Singh
Exactamente lo que he estado buscando. Gracias !
codesnooker
esto dará el resultado correcto: this.pad (Math.floor ((Math.abs (offset / 60))), 2)
Vivek
En lugar de usar la función de almohadilla, me resulta más fácil hacer esto: offset = (offset <0? "+": "-") + ("0000" + parseInt ((Math.abs (offset / 60)))) .slice (-4)
flurbius
67

Puedes usar:

zona horaria

<script src="moment.js"></script>
<script src="moment-timezone-with-data.js"></script>

// retrieve timezone by name (i.e. "America/Chicago")
moment.tz.guess();

La detección de la zona horaria del navegador es bastante difícil de hacer, ya que el navegador proporciona poca información.

Moment Timezone utiliza Date.getTimezoneOffset()y Date.toString()en un puñado de momentos durante el año en curso para recopilar tanta información sobre el entorno del navegador como sea posible. Luego compara esa información con todos los datos de zona horaria cargados y devuelve la coincidencia más cercana. En caso de empate, se devuelve la zona horaria con la ciudad con mayor población.

console.log(moment.tz.guess()); // America/Chicago
Sameer Ek
fuente
12
Esta debería ser la respuesta aceptada. Este es el único que da el nombre de la zona horaria real en lugar de compensar. Recuerde que el desplazamiento de la zona horaria se puede derivar del nombre, lo contrario no es cierto. Debido al horario de verano y otras sutilezas, varias zonas horarias pueden tener el mismo desplazamiento solo en algunos días específicos del año.
Romain G
1
Ahora hay una solución nativa para esto: la API Intl . Si bien moment.js fue una gran biblioteca en el pasado , actualmente hay alternativas mucho más pequeñas ( dayjs , date-fns ). El momento es enorme ; por favor no lo recomiende para aplicaciones cliente.
Dan Dascalescu
43

Escribí una función en mi proyecto, que devuelve la zona horaria en hh:mmformato. Espero que esto pueda ayudar a alguien:

function getTimeZone() {
    var offset = new Date().getTimezoneOffset(), o = Math.abs(offset);
    return (offset < 0 ? "+" : "-") + ("00" + Math.floor(o / 60)).slice(-2) + ":" + ("00" + (o % 60)).slice(-2);
}

// Outputs: +5:00

Violín de trabajo

SR verde
fuente
1
¡Gracias! ¡Esto es lo que necesitaba!
Jeremy Moritz el
15

Una línea que proporciona el desplazamiento y la zona horaria es simplemente llamar a toTimeString () en un nuevo objeto Date. De MDN:

El toTimeString()método devuelve la parte de tiempo de un objeto Date en forma legible para humanos en inglés americano.

El problema es que la zona horaria no está en el formato estándar de la IANA; es algo más fácil de usar que el formato IANA "continente / ciudad" . Pruébalo:

console.log(new Date().toTimeString().slice(9));
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone);
console.log(new Date().getTimezoneOffset() / -60);

En California en este momento, toTimeString()regresa Pacific Daylight Timemientras que la API Intl regresa America/Los_Angeles. En Colombia, obtendrías Colombia Standard Timevs.America/Bogota .

Tenga en cuenta que muchas otras respuestas a esta pregunta intentan obtener la misma información llamando a Date.toString (). Ese enfoque no es tan confiable, como explica MDN :

Las instancias de fecha se refieren a un punto específico en el tiempo. Llamar a toString () devolverá la fecha formateada en un formato legible por humanos en inglés americano. [...] Algunas veces es deseable obtener una cadena de la porción de tiempo; tal cosa se puede lograr con el toTimeString()método.

El toTimeString()método es especialmente útil porque los motores compatibles ejecución ECMA-262 pueden diferir en la secuencia obtenida a partir toString()de Datelos objetos, ya que el formato es dependiente de la implementación; Los enfoques simples de corte de cadenas pueden no producir resultados consistentes en múltiples motores.

Dan Dascalescu
fuente
13

prueba getTimezoneOffset()del Dateobjeto:

var curdate = new Date()
var offset = curdate.getTimezoneOffset()

Este método devuelve el desplazamiento de zona horaria en minutos, que es la diferencia entre GMT y la hora local en minutos.

dfa
fuente
9

JavaScript:

var d = new Date();
var n = d.getTimezoneOffset();
var timezone = n / -60;
console.log(timezone);

زياد
fuente
3
¿Qué proporciona esta respuesta que las respuestas anteriores no tienen?
Dan Dascalescu
7

Con moment.js :

moment().format('zz');
Kolypto
fuente
66
zy zzhan quedado en desuso a partir de 1.6.0 ver momentjs.com/docs/#/displaying/format
MrUpsidown
3
@MrUpsidown es ahora ZyZZ
brauliobo
44
@brauliobo Estos parámetros no devuelven lo mismo. z y zz devolvieron la zona horaria, por ejemplo, CST, pero Z y ZZ devolvieron el desplazamiento, por ejemplo, -0600.
Luca Spiller
El último programa de documentación .zoneAbbr()ha reemplazado zy zz. Ver documentación aquí
tabish89
1
Si bien moment.js fue una gran biblioteca en el pasado , actualmente hay alternativas mucho más pequeñas ( dayjs , date-fns ). El momento es enorme ; por favor no lo recomiende para aplicaciones cliente.
Dan Dascalescu
6

Con , puede encontrar la zona horaria actual como

console.log(moment().utcOffset()); // (-240, -120, -60, 0, 60, 120, 240, etc.)
<script src="https://cdn.jsdelivr.net/momentjs/2.13.0/moment.min.js"></script>


Con , puede encontrar la zona horaria actual como

console.log(dayjs().utcOffset()); // (-240, -120, -60, 0, 60, 120, 240, etc.)
<script src="https://unpkg.com/[email protected]/dayjs.min.js"></script>

Ambas API devuelven utc offset en minutos.

Fizer Khan
fuente
Si bien moment.js fue una gran biblioteca en el pasado , actualmente hay alternativas mucho más pequeñas ( dayjs , date-fns ). El momento es enorme ; por favor no lo recomiende para aplicaciones cliente.
Dan Dascalescu
1
"Con dayjs, puede encontrar la zona horaria actual como" no es exactamente exacto: solo encontrará el desplazamiento, no la zona horaria . Además, Dayjs no tiene soporte de zona horaria . Su método .utcOffset () es un contenedor simple sobre el nativo getTimezoneOffset().
Dan Dascalescu
4

Zona horaria en horas

var offset = new Date().getTimezoneOffset();
if(offset<0)
    console.log( "Your timezone is- GMT+" + (offset/-60));
else
    console.log( "Your timezone is- GMT-" + offset/60);

Si quieres ser preciso como mencionaste en el comentario, entonces deberías intentar así:

var offset = new Date().getTimezoneOffset();

if(offset<0)
{
    var extraZero = "";
    if(-offset%60<10)
      extraZero="0";

    console.log( "Your timezone is- GMT+" + Math.ceil(offset/-60)+":"+extraZero+(-offset%60));
}
else
{
    var extraZero = "";
    if(offset%60<10)
      extraZero="0";

    console.log( "Your timezone is- GMT-" + Math.floor(offset/60)+":"+extraZero+(offset%60));
}

Abrar Jahin
fuente
No funciona para zonas horarias cuando no es una hora completa, como Venezuela, donde regresa GMT-4.5
Mirko
Si, eso es correcto. 0.5 significa 0.5 * 30 minutos. Creo que tienes esto ¿por qué está dando 0.5?
Abrar Jahin
Sí, por lo que GMT-4.5 no es una zona horaria válida, necesita un poco de análisis adicional para convertirse en GMT-4: 30
Mirko
@Mirko ahora la segunda parte de la respuesta es para ti
Abrar Jahin
Si desea ser más preciso, use UTC en lugar de GMT, [Hilton y McCarthy 2013, p. 231–2. ], ver también en wikipedia GMT - ( en.wikipedia.org/wiki/Greenwich_Mean_Time )
Tom Kuschel
3

Si todo lo que necesita es la abreviatura de zona horaria "MST" o "EST":

function getTimeZone(){
    var now = new Date().toString();
    var timeZone = now.replace(/.*[(](.*)[)].*/,'$1');//extracts the content between parenthesis
    return timeZone;
}
JohnP2
fuente
El uso Date.toString()no es confiable, y MDN explica por qué. He pegado la sección relevante de sus documentos en mi respuesta .
Dan Dascalescu
3

Vea que este operador resultante era opuesto a la zona horaria. Por lo tanto, aplique alguna función matemática y luego valide el número menos o más.

ingrese la descripción de la imagen aquí

Ver el documento MDN

var a = new Date().getTimezoneOffset();

var res = -Math.round(a/60)+':'+-(a%60);
res = res < 0 ?res : '+'+res;

console.log(res)

prasanth
fuente
1
en caso de valor negativo, algún problema
Arun Prasad ES
1
¿Por qué round? Debería ser floor, ¿no?
Qwertiy
3
function getLocalTimeZone() {
    var dd = new Date();
    var ddStr = dd.toString();
    var ddArr = ddStr.split(' ');
    var tmznSTr = ddArr[5];
    tmznSTr = tmznSTr.substring(3, tmznSTr.length);
    return tmznSTr;
}

Ejemplo: jue 21 de junio de 2018 18:12:50 GMT + 0530 (hora estándar de India)

O / P: +0530

Chandrakanth Gowda
fuente
El uso Date.toString()no es confiable, y MDN explica por qué. He pegado la sección relevante de sus documentos en mi respuesta .
Dan Dascalescu
3

Prueba esto,

new Date().toString().split("GMT")[1].split(" (")[0]
Srinivasan Sekar
fuente
2

Este valor es de la máquina del usuario y se puede cambiar en cualquier momento, así que creo que no importa, solo quiero obtener un valor aproximado y luego convertirlo a GMT en mi servidor.

Por ejemplo, soy de Taiwán y me devuelve "+8".

Ejemplo de trabajo

JS

function timezone() {
    var offset = new Date().getTimezoneOffset();
    var minutes = Math.abs(offset);
    var hours = Math.floor(minutes / 60);
    var prefix = offset < 0 ? "+" : "-";
    return prefix+hours;
}


$('#result').html(timezone());

HTML

<div id="result"></div>

Resultado

+8
Terry Lin
fuente
2

En el new Date() puede obtener el desplazamiento, para obtener el nombre de la zona horaria que puede hacer:

new Date().toString().replace(/(.*\((.*)\).*)/, '$2');

obtienes el valor entre ()al final de la fecha, ese es el nombre de la zona horaria.

Moysés Lacerda
fuente
El uso Date.toString()no es confiable, y MDN explica por qué. He pegado la sección relevante de sus documentos en mi respuesta . Además, esta respuesta ya se ha dado al menos 3 veces.
Dan Dascalescu
2

Esta sería mi solución:


    // For time zone:
    const timeZone = /\((.*)\)/.exec(new Date().toString())[1];
    
    // Offset hours:
    const offsetHours = new Date().getTimezoneOffset() / 60;
    
    console.log(`${timeZone}, ${offsetHours}hrs`);

fuente
1

Como alternativa a new Date().getTimezoneOffset()y moment().format('zz'), también puede usar:

var offset = moment.parseZone(Date.now()).utcOffset() / 60
console.log(offset);
<script src="https://cdn.jsdelivr.net/momentjs/2.13.0/moment.min.js"></script>

jstimezone también es bastante defectuoso y no se mantiene ( https://bitbucket.org/pellepim/jstimezonedetect/issues?status=new&status=open )

brauliobo
fuente
Si bien moment.js fue una gran biblioteca en el pasado , actualmente hay alternativas mucho más pequeñas ( dayjs , date-fns ). El momento es enorme ; por favor no lo recomiende para aplicaciones cliente.
Dan Dascalescu
1

Use esto para convertir OffSet a positivo:

var offset = new Date().getTimezoneOffset();
console.log(offset);
this.timeOffSet = offset + (-2*offset);
console.log(this.timeOffSet);
Kumal Pereira
fuente
-2

Estaba buscando solo la cadena de 3 letras (como "PDT") y probé la respuesta de Márquez, pero tuve que ajustarla un poco para que fuera compatible con el navegador cruzado. Afortunadamente, la cadena es la última coincidencia potencial :)

Esto es lo que hice, en CoffeeScript:

browserTimezone = ->
  userDate = new Date()
  zoneMatches = userDate.toString().match(/([A-Z][A-Z][A-Z])/g)
  userZone = zoneMatches[zoneMatches.length - 1]

Funciona en IE8, IE9, Safari 9, Firefox 44 y Chrome 48

ari gold
fuente
2
Sin embargo, hay zonas horarias con 4 letras: tenga cuidado: CEST, por ejemplo (horario de verano de Europa Central)
jbrosi,
El uso Date.toString()no es confiable, y MDN explica por qué. He pegado la sección relevante de sus documentos en mi respuesta .
Dan Dascalescu
-3

Solo debes incluir moment.js y jstz.js

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.6/jstz.min.js"></script>

y después de eso

<script>
$(function(){
 var currentTimezone = jstz.determine();
 var timezone = currentTimezone.name();
 alert(timezone);
});

</script>
Dayachand Patel
fuente
-3

Este es un muy buen trabajo para mí:

// Translation to offset in Unix Timestamp
let timeZoneOffset = ((new Date().getTimezoneOffset())/60)*3600;
Alejandro
fuente
1
Alguna explicación?
-4

simplemente puedes probar esto. le devolverá el tiempo actual de la máquina

var _d = new Date(), t = 0, d = new Date(t*1000 + _d.getTime())

usuario8066707
fuente
Así es como debería hacerse, creo: new Date(new Date().getTime()); mostraría: "Vie 28 de diciembre de 2018 10:15:23 GMT + 0100 (Hora estándar de Europa Central) {}"
darmis
-4

Esto hará el trabajo.


var time = new Date(),
timestamp = Date(1000 + time.getTime());
console.log(timestamp);

Thu May 25 2017 21:35:14 GMT+0300 (IDT)

indefinido

SysMurff
fuente