2011-03-18 15 views
16

Estoy construyendo un sitio que tiene los tiempos y precios marcados. Lo que más me preocupa es sincronizar el tiempo para que sea lo más preciso posible en todos los clientes.Cómo sincronizar una cuenta atrás de javascript con la hora del servidor

Actualmente, le estoy enviando al cliente la cantidad de milisegundos restantes que se utilizan para alimentar el temporizador de cuenta atrás, pero debido a retrasos en la transferencia y la reproducción, puede estar apagado varios segundos incluso con 2 navegadores en la misma computadora.

¿Hay alguna manera de sincronizar el tiempo de JavaScript del servidor y el tiempo del servidor, o voy a tener que lidiar con este ligero retraso?

Si hubiera una forma de medir con precisión la diferencia de tiempo entre el servidor que envía los datos y que el cliente los reciba y los entregue.

+0

¿qué piensa usted acerca de alimentar el temporizador de cuenta atrás a través de una llamada AJAX después de que la página se ha cargado, usted podría en un principio no mostrar la contrarrestar escondiéndolo, luego mostrar en éxito de jajax. La solicitud sería mucho más rápida ya que no está haciendo una publicación de página completa. –

Respuesta

17

Aunque el tiempo en el servidor y el cliente va a ser diferente, la velocidad a la que cambia el tiempo debería ser esencialmente la misma. Enviaría el tiempo restante al cliente, dejaré que el cliente agregue ese tiempo a la hora actual y luego haré que el cliente calcule la cuenta regresiva a partir de eso. Por ejemplo:

var timeRemaining = [rendered on page load or queried by ajax]; // in milliseconds 
var endTime = new Date(new Date().getTime() + timeRemaining); 

// Put this in a setInterval, or however you currently handle it 
var countdown = (endTime.getTime() - new Date().getTime())/1000; 
+4

Tenga en cuenta que si completa el tiempo restante en la carga de la página, a veces el navegador web almacena en caché la página, y esta versión almacenada en caché se procesará si el usuario navega fuera de la página y regresa a ella mediante el botón Atrás. En este caso, el temporizador parecerá que no se ha movido en absoluto (porque el tiempo restante permanece en la memoria caché y sin cambios). Difícil de hecho. – stereoscott

+0

No puedo entender esto ¿a qué te refieres con la tasa de cambio de tiempo? cuando el servidor calcula el tiempo restante, entonces envíelo ¿dónde está la demora para el retraso de respuesta? –

+0

@Doggynub tasa de cambio de tiempo significa 1 segundo en el cliente es lo mismo que 1 segundo en el servidor. – ian

1

Puede medir el tiempo que toma la ida y vuelta completa del servidor y dividir por dos para obtener una buena estimación de la diferencia horaria. Tenga cuidado: no se garantiza que los paquetes de IP tomen la misma ruta en ambas direcciones, pero la propagación es bastante alta.

Puede usar Date.getTime() si la resolución de milisegundos es suficiente para usted.

+0

Además de un desplazamiento para cualquier diferencia que tengan los relojes del servidor y del sistema cliente. –

0

La solución a esto es Javascript: puede acceder a la configuración de zona horaria en el cliente. Lamentablemente, solo puede obtener compensaciones de zona horaria (especificadas en minutos) para fechas específicas, sin nombre de zona horaria. Así que para determinar la zona horaria correcta también necesitamos saber si el horario de verano (DST) se está empleando - esta es la parte del lado del cliente de la solución:

var now = new Date(); 
var later = new Date(); 
// Set time for how long the cookie should be saved 
later.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); 
// Set cookie for the time zone offset in minutes 
setCookie("time_zone_offset", now.getTimezoneOffset(), later, "/"); 
// Create two new dates 
var d1 = new Date(); 
var d2 = new Date(); 
// Date one is set to January 1st of this year 
// Guaranteed not to be in DST for northern hemisphere, 
// and guaranteed to be in DST for southern hemisphere 
// (If DST exists on client PC) 
d1.setDate(1); 
d1.setMonth(1); 
// Date two is set to July 1st of this year 
// Guaranteed to be in DST for northern hemisphere, 
// and guaranteed not to be in DST for southern hemisphere 
// (If DST exists on client PC) 
d2.setDate(1); 
d2.setMonth(7); 
// If time zone offsets match, no DST exists for this time zone 
if(parseInt(d1.getTimezoneOffset())==parseInt(d2.getTimezoneOffset())) 
{ 
setCookie("time_zone_dst", "0", later, "/"); 
} 
// DST exists for this time zone – check if it is currently active 
else { 
// Find out if we are on northern or southern hemisphere 
// Hemisphere is positive for northern, and negative for southern 
var hemisphere = parseInt(d1.getTimezoneOffset())-parseInt(d2.getTimezoneOffset()); 
// Current date is still before or after DST, not containing DST 
if((hemisphere>0 && parseInt(d1.getTimezoneOffset())==parseInt(now.getTimezoneOffset())) || 
(hemisphere<0 && parseInt(d2.getTimezoneOffset())==parseInt(now.getTimezoneOffset()))) { setCookie("time_zone_dst", "0", later, "/"); } // DST is active right now with the current date else { setCookie("time_zone_dst", "1", later, "/"); } } 

guardar los resultados como galletas, que puede ser accedido por su script PHP. Debe incluir el código anterior en al menos la primera página a la que accede un usuario; lo incluyo en cada página para reconocer (y adaptarme) a los cambios, incluso si dichos cambios durante una sesión son improbables.

En PHP puede extraer un huso horario válido con una nueva función llamada timezone_name_from_abbr, disponible desde PHP 5.1.3 - toma una abreviación de zona horaria o una combinación de desplazamiento de zona horaria (en segundos) y horario de verano, y tenemos la última combinación:

$time_zone_name = timezone_name_from_abbr(", -$_COOKIE['time_zone_offset']*60, $_COOKIE['time_zone_dst']); 

esto le dará un nombre de zona horaria correcta para el usuario, si los datos de las cookies es válida - en cuenta que hay muchos nombres “duplicado”, por ejemplo “Europa/Berlín "y" Europa/Zurich ", que tienen exactamente la misma configuración de zona horaria (al menos por ahora), y puede obtener cualquiera de ellos para las variables correspondientes de desplazamiento y DST. La lista de nombres de zonas horarias se puede encontrar en la Lista de zonas horarias compatibles en php.net.

Creación de cadenas de fecha con una zona horaria determinada Con el nombre de la zona horaria del usuario ahora puede utilizar las clases PHP DateTimeZone y DateTime para crear, finalmente, las cadenas de fecha con la zona horaria correcta:

// Create time zone class 
$time_zone_class = new DateTimeZone($time_zone_name); 
// Create new date class with a given date 
// Notice that the provided date will be regarded as being in the 
// default time zone and converted accordingly 
$new_date = new DateTime(‘2007-02-14 15:30:00′, $time_zone_class); 
// Print date with the user’s time zone echo $new_date->format(‘Y-m-d H:i:s’); 

¡Eso es todo!

Fuente: http://togl.me/eE2

10

Hay una manera de sincronizar los datetimes de tiempo JavaScript del cliente y la hora del servidor. Escribí una biblioteca que hace exactamente esto: ServerDate.

Aquí es parte de la README:

Puede utilizar ServerDate de igual modo que la función Date o uno de sus casos, por ejemplo:

> ServerDate() 
"Mon Aug 13 2012 20:26:34 GMT-0300 (ART)" 

> ServerDate.now() 
1344900478753 

> ServerDate.getMilliseconds() 
22 

También hay un nuevo método para obtener el la precisión de la estimación del reloj del servidor de ServerDate (en milisegundos):

> ServerDate.toLocaleString() + " ± " + ServerDate.getPrecision() + " ms" 
"Tue Aug 14 01:01:49 2012 ± 108 ms" 

Se puede ver la diferencia entre el reloj del servidor y el reloj de los navegadores, en milisegundos:

> ServerDate - new Date() 
39 
Cuestiones relacionadas