2012-08-09 28 views
106

Esto es un poco de mi código JS para los que esto es necesario:Cómo verificar si el horario de verano (DST) está vigente y si es el límite?

var secDiff=Math.abs(Math.round((utc_date-this.premiere_date)/1000)); 
this.years=this.calculateUnit(secDiff,(86400*365)); 
this.days=this.calculateUnit(secDiff-(this.years*(86400*365)),86400); 
this.hours=this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)),3600); 
this.minutes=this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)-(this.hours*3600)),60); 
this.seconds=this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)-(this.hours*3600)-(this.minutes*60)),1); 

Quiero conseguir la fecha y hora de atrás, pero si el horario de verano está en uso a continuación, las fechas son de por 1 hora. No sé cómo verificar si el horario de verano está en uso o no.

¿Cómo puedo saber cuándo comienza y finaliza el horario de verano?

Respuesta

233

El código proporcionado por enlace obsoleto le dirá si el horario de verano está vigente. Utiliza el hecho de que getTimezoneOffset devuelve un valor diferente durante el horario de verano y el horario estándar, y compara la diferencia entre los dos. (Por ejemplo, Nueva York devuelve -5 normalmente y -4 durante horario de verano)

Tenga en cuenta que no tengo idea de las complejidades de las zonas horarias internacionales, y solo he probado que devuelve resultados correctos para mi zona horaria .. pero el código parece sólido.

var today = new Date(); 
if (today.dst()) { alert ("Daylight savings time!"); } 

Date.prototype.stdTimezoneOffset = function() { 
    var jan = new Date(this.getFullYear(), 0, 1); 
    var jul = new Date(this.getFullYear(), 6, 1); 
    return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); 
} 

Date.prototype.dst = function() { 
    return this.getTimezoneOffset() < this.stdTimezoneOffset(); 
} 
+19

puedo comprobar que esto trabaja a nivel internacional. Actualmente no hay zonas horarias que usen cualquier forma de horario de verano donde tanto el 1 de enero como el 1 de julio estén dentro o fuera del período de horario de verano. Además, en todas las zonas horarias en el TZDB ([con una excepción trivial] (http://en.wikipedia.org/wiki/Antarctica/Casey)) el mayor de los dos desplazamientos es el desplazamiento DST. Dado que el 'getTimezoneOffset' de JavaScript devuelve el valor inverso,' Math.max' devuelve el desplazamiento * estándar *. El código es correcto –

+3

Sin embargo, si alguna zona horaria cambia su definición de modo que tanto el 1 de enero como el 1 de julio son ambos en horario de verano o ambos * no * en horario de verano (y el horario de verano todavía se aplica), este código no funcionaría en esa zona. –

+3

Esto funciona genial. Es realmente agradable poder establecer una constante interna como: 'TIMEZONE_OFFSET = ((new Date()) dst())?'-04: 00': '-05: 00'' – nessur

16

Crea dos fechas: una en junio y otra en enero. Compare sus valores getTimezoneOffset().

  • si enero compensado> Junio ​​compensado, el cliente se encuentra en el hemisferio norte
  • si enero compensado < junio compensado, el cliente se encuentra en el hemisferio sur
  • si hay diferencia, la zona horaria del cliente no observa el horario de verano

Ahora comprueba getTimezoneOffset() de la fecha actual.

  • si es igual a junio, hemisferio norte, a continuación, la zona horaria actual es el horario de verano (+1 hora)
  • si es igual de enero de hemisferio sur, a continuación, la zona horaria actual es el horario de verano (+1 hora)
+0

¿Por qué necesitas los hemisferios? ¿No sería suficiente decir que si getTimezoneOffset() para la fecha actual es igual a la más pequeña de las dos getTimezoneOffset() entonces su DST? [y el desplazamiento es la diferencia entre los dos?] – epeleg

+0

No necesita los hemisferios, ya que la respuesta aceptada lo demuestra claramente :) –

+0

Esto no funcionará. Lo mejor que puede hacer es asegurarse de utilizar las horas UTC y establecer manualmente el desplazamiento para la región que desea. A continuación, busque manualmente el inicio y el final para el horario de verano para la misma región (si corresponde). Luego desea verificar si la hora de esa región está dentro del rango DST o no, y luego actualizar el desplazamiento correspondiente con +1. Esto hace que sea posible comparar países que observan DST y aquellos que no. – Kebman

11

me encontré con este mismo problema hoy, pero ya que nuestros arranques de ahorro de luz del día y se detiene en diversos tiempos entre los EE.UU. (al menos desde mi entendimiento), he utilizado una ruta ligeramente diferente ..

var arr = []; 
for (var i = 0; i < 365; i++) { 
var d = new Date(); 
d.setDate(i); 
newoffset = d.getTimezoneOffset(); 
arr.push(newoffset); 
} 
DST = Math.min.apply(null, arr); 
nonDST = Math.max.apply(null, arr); 

Luego, simplemente compare la compensación actual de la zona horaria con DST y nonDST para ver cuál coincide.

+0

Así es como lo hacemos también. Es decir, determine las horas del año en que cambia el horario de verano en su zona horaria objetivo y calcule las compensaciones para el día actual y la fecha de cambio más reciente. Diferirán por una hora o serán iguales (suponiendo que el huso horario en cuestión es una compensación de hora). – Heather

+0

No es necesario crear 365 valores, un enfoque de búsqueda binaria que se detiene tan pronto como se determina un cambio en la compensación debe ser mucho más eficiente, incluso cuando no se respete el horario de verano. Todos estos enfoques suponen que los lugares observan el horario de verano cada año, lo que no es necesariamente cierto. Los lugares adoptan y abandonan el horario de verano de vez en cuando (aunque ECMAScript asume que las reglas actuales, cualquiera que sea su área, se aplican siempre). – RobG

+1

Rob: ¿cómo puedes hacer esto a través de una búsqueda binaria si no sabes dónde buscar (es decir, el lugar que buscas está arriba o debajo de tu punto de prueba?) – epeleg

7

Basado en el comentario de Matt Johanson en la solución proporcionada por Sheldon Griffin creé el siguiente código:

Date.prototype.stdTimezoneOffset = function() { 
     var fy=this.getFullYear(); 
     if (!Date.prototype.stdTimezoneOffset.cache.hasOwnProperty(fy)) { 

      var maxOffset = new Date(fy, 0, 1).getTimezoneOffset(); 
      var monthsTestOrder=[6,7,5,8,4,9,3,10,2,11,1]; 

      for(var mi=0;mi<12;mi++) { 
       var offset=new Date(fy, monthsTestOrder[mi], 1).getTimezoneOffset(); 
       if (offset!=maxOffset) { 
        maxOffset=Math.max(maxOffset,offset); 
        break; 
       } 
      } 
      Date.prototype.stdTimezoneOffset.cache[fy]=maxOffset; 
     } 
     return Date.prototype.stdTimezoneOffset.cache[fy]; 
    }; 

    Date.prototype.stdTimezoneOffset.cache={}; 

    Date.prototype.isDST = function() { 
     return this.getTimezoneOffset() < this.stdTimezoneOffset(); 
    }; 

Se trata de obtener el mejor de los mundos, teniendo en cuenta todos los comentarios y respuestas previamente sugeridas y, específicamente, it:

1) Almacena en caché el resultado por año de stdTimezoneOffset para que no tenga que volver a calcularlo cuando pruebe varias fechas en el mismo año.

2) No supone que el horario de verano (si es que existe) es necesariamente en julio, y funcionará aunque en algún momento y en algún lugar sea en cualquier mes. Sin embargo, en cuanto a rendimiento, funcionará más rápido si, de hecho, julio (o cerca de meses) son realmente DST.

3) Peor caso, comparará el getTimezoneOffset del primero de cada mes. [y hacer eso una vez por año probado].

La suposición que todavía hace es que si el período de DST es más grande que un solo mes.

Si alguien quiere eliminar esa suposición, puede cambiar el bucle en algo más como lo que está en la solución provista por Aaron Cole, pero aún así saltaría medio año antes y saldrá del ciclo cuando se encuentren dos compensaciones diferentes.

1

Estás cerca pero un poco apagado. Nunca necesita calcular su propio tiempo, ya que es el resultado de su propio reloj. Es capaz de detectar si está utilizando el horario de verano en su ubicación pero no para una ubicación remota producido por el desplazamiento:

newDateWithOffset = new Date(utc + (3600000*(offset))); 

Esto seguirá siendo mal y fuera de una hora si se encuentran en el horario de verano. Necesita una cuenta de tiempo remota si están actualmente dentro de su horario de verano o no y ajuste en consecuencia. intente calcular esto y cambie su reloj a - digamos 2/1/2015 y restablezca el reloj una hora atrás como fuera del horario de verano. Luego calcule para una compensación para un lugar que aún debe estar 2 horas atrás. Aparecerá una hora antes de la ventana de dos horas. Aún necesitaría tener en cuenta la hora y ajustar. Lo hice para Nueva York y Denver y siempre voy mal (hora adelante) en Denver.

5

Ya solucionado, pero pensé que debería agregar la forma en que lo hago (en caso de que a las personas les interese).

function isDST(t) { //t is the date object to check, returns true if daylight saving time is in effect. 
    var jan = new Date(t.getFullYear(),0,1); 
    var jul = new Date(t.getFullYear(),6,1); 
    return Math.min(jan.getTimezoneOffset(),jul.getTimezoneOffset()) == t.getTimezoneOffset(); 
} 

funciona de la misma manera que la respuesta exceptuado (offset janurary y julio de zona horaria), a continuación, devuelve el condicional.

0

recientemente que necesitaba para crear una cadena de fecha con la hora UTC y horario de verano, y basado en la respuesta de Sheldon pongo esto juntos:

Date.prototype.getTimezone = function(showDST) { 
 
    var jan = new Date(this.getFullYear(), 0, 1); 
 
    var jul = new Date(this.getFullYear(), 6, 1); 
 

 
    var utcOffset = new Date().getTimezoneOffset()/60 * -1; 
 
    var dstOffset = (jan.getTimezoneOffset() - jul.getTimezoneOffset())/60; 
 

 
    var utc = "UTC" + utcOffset.getSign() + (utcOffset * 100).preFixed(1000); 
 
    var dst = "DST" + dstOffset.getSign() + (dstOffset * 100).preFixed(1000); 
 

 
    if (showDST) { 
 
     return utc + " (" + dst + ")"; 
 
    } 
 

 
    return utc; 
 
} 
 
Number.prototype.preFixed = function (preCeiling) { 
 
    var num = parseInt(this, 10); 
 
    if (preCeiling && num < preCeiling) { 
 
     num = Math.abs(num); 
 
     var numLength \t \t = num.toString().length; 
 
     var preCeilingLength = preCeiling.toString().length; 
 
     var preOffset \t \t = preCeilingLength - numLength; 
 
     for (var i = 0; i < preOffset; i++) { 
 
      num = "0" + num; 
 
     } 
 
    } 
 
    return num; 
 
} 
 
Number.prototype.getSign = function() { 
 
    var num \t = parseInt(this, 10); 
 
    var sign = "+"; 
 
    if (num < 0) { 
 
     sign = "-"; 
 
    } 
 
    return sign; 
 
} 
 

 
document.body.innerHTML += new Date().getTimezone() + "<br>"; 
 
document.body.innerHTML += new Date().getTimezone(true);
<p>Output for Turkey (UTC+0200) and currently in DST: &nbsp; UTC+0300 (DST+0100)</p> 
 
<hr>

1

La biblioteca moment.js proporciona un método .isDst() en su momento objetos.

momento # isDST comprueba si el momento actual es en horario de verano.

moment([2011, 2, 12]).isDST(); // false, March 12 2011 is not DST 
moment([2011, 2, 14]).isDST(); // true, March 14 2011 is DST 
0

que he encontrado que el uso de la biblioteca Moment.js con algunos de los conceptos descritos aquí (comparando enero a junio) funciona muy bien.

Esta simple función devolverá si la zona horaria que se encuentra el usuario observa el horario de verano:

function HasDST() { 
    return moment([2017, 1, 1]).isDST() != moment([2017, 6, 1]).isDST(); 
} 

Una forma sencilla de comprobar que esto funciona (en Windows) es cambiar su zona horaria a un no el horario de verano zona, por ejemplo Arizona devolverá falso, mientras que EST o PST volverán verdadero.

enter image description here

0

El método getTimezoneOffset() en JavaScript, en un navegador, devuelve el número de minutos de desplazamiento desde la zona de las 00:00 hora.Por ejemplo, la zona horaria América/Nueva_York en Horario de verano (DST) devuelve el número 300. 300 minutos es una diferencia de 5 horas desde cero. 300 minutos divididos por 60 minutos son 5 horas. Cada zona horaria se compara con la zona horaria cero, +00: 00/Etc/GMT/hora de Greenwich.

MDN Web Docs

La siguiente cosa que usted debe saber, es que el desplazamiento tiene el signo opuesto de la zona de tiempo real.

Información sobre las zonas de tiempo se mantiene por la Autoridad de Números Asignados de Internet (IANA)

iana time zones

Una tabla de un formato agradable de zonas de horario es suministrada por joda.org

joda-time Time Zones

+00: 00 o Etc/GMT es la hora de Greenwich

Todas las zonas horarias ar e desplazamiento desde +00: 00/"Etc/GMT"/hora de Greenwich

Horario de verano es siempre un momento anterior a la hora "normal" en el verano. Usted establece sus relojes en la temporada de otoño. (Lema "Fall Back" para recordar qué hacer)

Por lo tanto, America/New_York en horario de verano (invierno) es una hora antes del horario habitual. Entonces, por ejemplo, lo que normalmente era a las 5 p.m. por la tarde en la ciudad de Nueva York en el verano, ahora son las 4 p.m. Hora de America/New_York en horario de verano. El nombre "America/New_York" time es un nombre de zona horaria "Long Format". La costa este de EE. UU. Normalmente llama a su zona horaria Eastern Standard Time (EST)

Si desea comparar el desplazamiento de la zona horaria de hoy con el desfase de la zona horaria de alguna otra fecha, necesita saber ese signo matemático (+/- "Positivo/Negativo") del desplazamiento de la zona horaria es el opuesto al huso horario.

Mire la tabla de zonas horarias en joda.org y encuentre la zona horaria para "America/New_York" Tendrá un signo negativo en frente de la compensación estándar.

La tierra gira en sentido antihorario en su eje. Una persona que mira el amanecer en Greenwich ve el amanecer 5 horas antes de que alguien en la ciudad de Nueva York vea el amanecer. Y alguien en la costa oeste de EE. UU. Verá el amanecer después de que alguien en la costa este de los EE. UU. Vea el amanecer.

Hay una razón por la que necesita saber todo esto. Para que pueda determinar de forma lógica si algún código JavaScript obtiene el estado de DST correctamente o no, sin necesidad de probar cada zona horaria en diferentes momentos del año.

Imagine que es noviembre en la ciudad de Nueva York, y los relojes se han retrasado una hora. En el verano en la ciudad de Nueva York, el desplazamiento es de 240 minutos o 4 horas.

Puede probar esto creando una fecha en julio y luego obteniendo el desplazamiento.

var July_Date = new Date(2017, 6, 1); 
var july_Timezone_OffSet = July_Date.getTimezoneOffset(); 

console.log('july_Timezone_OffSet: ' + july_Timezone_OffSet) 

¿Qué se imprimirá en el registro de la consola de herramientas del desarrollador del navegador?

respuesta es: 240

Por lo tanto, ahora se puede crear una fecha en enero y ver lo que su navegador vuelve para un desplazamiento de zona horaria para la temporada de invierno.

var Jan_Date = new Date(2017, 0, 1);//Month is zero indexed - Jan is zero 
var jan_Timezone_OffSet = Jan_Date.getTimezoneOffset(); 

console.log('jan_Timezone_OffSet: ' + jan_Timezone_OffSet) 

respuesta es: 300

Obviamente 300 es mayor que 240. Por lo tanto, ¿qué significa esto? ¿Debería escribir un código que pruebe que el offset de invierno es más grande que el offset de verano? ¿O el verano compensa menos que el desplazamiento de invierno? Si hay una diferencia entre los desplazamientos de zona horaria de verano y de invierno, puede suponer que se está utilizando el horario de verano para esta zona horaria. Pero eso no le dice si hoy está utilizando DST para la zona horaria de los navegadores. Por lo tanto, deberá obtener la compensación de zona horaria para hoy.

var today = new Date(); 
var todaysTimeZone = today.getTimezoneOffset(); 

console.log('todaysTimeZone : ' + todaysTimeZone) 

Responder es:? - Depende de la época del año

Si la zona horaria actual offset y el huso horario de verano de desplazamiento es el mismo, Y el tiempo de los desplazamientos de la zona de verano e invierno son diferentes, por deducción lógica, en la actualidad se debe no estar en DST.

¿Puede omitir la comparación de los desplazamientos de zona horaria de verano y de invierno, (saber si se utiliza DST para este huso horario) y simplemente comparar el desplazamiento de zona horaria actual con el desplazamiento de verano TZ y obtener siempre la respuesta correcta?

today's TZ Offset !== Summer TZ Offset 

Bueno, ¿hoy es invierno o verano? Si usted supiera que entonces se podría aplicar la siguiente lógica:

if (it_is_winter && (todays_TZ_Offset !== summer_TZ_Offset) { 
    var are_We_In_DST = true; 
} 

Pero el problema es, que no se sabe si la fecha de hoy es en invierno o verano. Cada zona horaria puede tener sus propias reglas para cuando el horario de verano comience y se detenga. Tendría que hacer un seguimiento de las reglas de cada zona horaria para cada zona horaria del mundo. Por lo tanto, si hay una manera mejor y más fácil, entonces también puede hacerlo de la mejor manera y más fácil.

Lo que nos queda es que usted necesita saber si esta zona horaria usa DST, y luego comparar la compensación de la zona horaria de hoy con la compensación de la zona horaria de verano. Eso siempre te dará una respuesta confiable.

La lógica final es:

if (DST_Is_Used_In_This_Time_Zone && (todays_TZ_Offset !== summer_TZ_Offset) { 
    var are_We_In_DST = true; 
} 

función para determinar si la zona horaria en el navegador utiliza el horario de verano:

function is_DST_Used_In_This_TimeZone() { 
    var Jan_Date, jan_Timezone_OffSet, July_Date, july_Timezone_OffSet 
     offsetsNotEqual, thisYear, today; 

    today = new Date();//Create a date object that is now 
    thisYear = today.getFullYear();//Get the year as a number 

    Jan_Date = new Date(thisYear, 0, 1);//Month is zero indexed - Jan is zero 
    jan_Timezone_OffSet = Jan_Date.getTimezoneOffset(); 

    console.log('jan_Timezone_OffSet: ' + jan_Timezone_OffSet) 

    July_Date = new Date(thisYear, 6, 1); 
    july_Timezone_OffSet = July_Date.getTimezoneOffset(); 

    console.log('july_Timezone_OffSet: ' + july_Timezone_OffSet) 

    offsetsNotEqual = july_Timezone_OffSet !== jan_Timezone_OffSet;//True if not equal 

    console.log('offsetsNotEqual: ' + offsetsNotEqual); 

    return offsetsNotEqual;//If the offsets are not equal for summer and 
     //winter then the only possible reason is that DST is used for 
     //this time zone 
} 
Cuestiones relacionadas