¿Cómo puedo manejar las zonas horarias en mi aplicación web?

106

Estoy buscando una mejor comprensión de la siguiente historia de usuario:

John trabaja en Sidney. A las 9:00 de la mañana, registra un evento en una aplicación web que se ejecuta en un servidor en Zurich. Al día siguiente, viaja a Nueva York para una reunión de emergencia en la que se debe discutir el evento. Durante la reunión, busca el evento por fecha y hora.

Como lo veo, hay al menos dos problemas aquí:

  1. ¿Cómo debo guardar las marcas de tiempo en la base de datos?
  2. ¿Cómo debo presentarlos en la interfaz de usuario?

Cuando John busque el evento, sabrá que sucedió a las 9:00, pero ¿qué debe ingresar en el navegador web? No encontrará nada cuando ingrese "9:00" como marca de tiempo porque podría ser la hora de Zúrich o Nueva York (dado que no se ha encontrado el evento, la aplicación no tiene forma de saber que sucedió en Sidney, por lo que no puede seleccionar automáticamente la zona horaria correcta).

¿Cuál es una buena forma de pedirle al usuario una marca de tiempo que pueda incluir la zona horaria?

El segundo problema es cómo mostrar los resultados. Si equipos de todo el mundo necesitan discutir el evento (y encontrar eventos relacionados, piense en un ataque de cracker que se dirija a varios sitios en todo el mundo a la vez).

¿Cuál es un buen ejemplo para mostrar marcas de tiempo que podrían haberse creado en una zona horaria diferente?

Nota: Concéntrese en la usabilidad del requisito. Yo mismo puedo averiguar el mapeo de la base de datos. Actualmente, no estoy seguro del flujo de trabajo. Debe solicitar / presentar la información necesaria de una manera no intrusiva / intuitiva. Si puede, proporcione un enlace a una aplicación web existente que ya resuelva esto.

Aaron Digulla
fuente
5
Stack Overflow resuelve esto poniendo todo en UTC. No siempre es conveniente, pero definitivamente no es ambiguo, no es difícil de implementar y funciona.
Ry-
2
UTC es tentador, pero OTOH, SO nunca necesita sincronizar eventos en varias zonas horarias.
Aaron Digulla
3
¿Qué pasa si uno de los países involucrados promulga una legislación que cambia la hora local después de la programación del evento, pero antes de que ocurra? ¿Cómo debería manejar esto el sistema? en.wikipedia.org/wiki/…
Julius Musseau
1
Este tipo de pregunta clásica sobre la zona horaria ha sido tan golpeada durante décadas en Internet y en forma impresa, ¡me sorprende ver comentarios tan animados y recompensas en esta pregunta!
BenSwayne
2
Yo agrego un punto adicional de complejidad al señalar lo obvio, a saber, que la mayor parte del mundo occidental cambia de zona horaria dos veces al año ("horario de verano"), y que las reglas para cuando esto ocurre no son uniformes a nivel mundial ni necesariamente triviales. algorítmicamente hablando?
viernes 13 de

Respuestas:

99

El problema de almacenar marcas de tiempo es simple: guárdelos en UTC.

En cuanto a mostrarlos, tendría sentido tomar la configuración de la zona horaria del dispositivo y usarla como la zona horaria actual. Dicho esto, debería haber un menú desplegable de zona horaria junto al cuadro de "entrada de tiempo", que por defecto es la zona horaria actual del dispositivo, para que el usuario pueda cambiarla si es necesario.

La mayoría de sus usuarios probablemente no cambiarán las zonas horarias mucho, o en absoluto. En su mayor parte, la situación que describió es poco común. Al implementar un menú desplegable con un valor predeterminado adecuado, debería poder facilitar las cosas a quienes se mueven (porque normalmente comprenden mejor las zonas horarias que un no viajero).

De hecho, sería incluso mejor guardar la zona horaria en la que se configuró el dispositivo cuando se ejecutó la aplicación por primera vez y luego ver si alguna vez cambia. Si cambia, entonces el usuario probablemente sea un viajero y probablemente se beneficiaría de tener el menú desplegable de zona horaria. De lo contrario, simplemente no muestre el menú desplegable y por defecto la zona horaria del dispositivo (porque el usuario no necesita conocerlos). En cualquier caso, tenga una configuración en la aplicación que le permita al usuario mostrar / ocultar manualmente el menú desplegable de zona horaria.


Para resumir lo anterior:

  • En la primera ejecución, guarde la zona horaria en la que está configurado el dispositivo.
  • Utilice esa zona horaria como la zona horaria predeterminada. Asume siempre esa zona horaria.
  • Si el dispositivo cambia de zona horaria, agregue un menú desplegable para seleccionar en qué zona horaria se encuentra el evento, de manera predeterminada a la propia zona horaria del dispositivo.
  • Agregue una opción para mostrar / ocultar este menú desplegable de zona horaria manualmente.
  • Almacene siempre las marcas de tiempo en UTC.
Niet the Dark Absol
fuente
¿Qué queremos decir con "zona horaria"? Parece que se utiliza de forma ambigua. Esto parece una referencia: en.wikipedia.org/wiki/Tz_database Por lo que puedo decir, una "zona horaria" es "Área / Ubicación", por ejemplo, "América / New_York". Eso parece ser geográfico, lo cual es genial porque, por ejemplo, America / Los_Angeles significa AMBOS PST y PDT dependiendo de si el mundo está operando en horario de verano. Y si ese es el caso, la pregunta es ¿cómo contabilizamos los cambios bianuales en la compensación UTC para las zonas? Además, ¿cómo llamamos a esas apreciaciones ya que no son "zonas" geográficamente, verdad?
iJames
Esta es una respuesta genial. ¿Existe alguna práctica recomendada sobre cómo almacenar la información de la zona horaria? Por ejemplo, ¿cuál sería mejor, 'PST' o 'América / Pacífico'? ¿Cómo podré convertir fácilmente una marca de tiempo en UTC a la zona horaria del usuario capturado? Se agradecería cualquier mejor práctica al respecto.
Patthebug
27

En nuestras aplicaciones, generalmente almacenamos la zona horaria del usuario cuando nos registramos por primera vez, como se ve a menudo en los sitios de foros, y siempre mostramos la hora con la zona horaria .

En cuanto a almacenar las fechas, UTC es el camino a seguir. Convierta a UTC y péguelo en la base de datos. Mientras recupera, simplemente convierta la hora a la zona horaria establecida para el usuario.

Tuve que resolver un caso de uso similar, en el que se podían enviar notificaciones personalizadas, como "Feliz año nuevo", a todos los usuarios de la aplicación web. Dado que los usuarios están repartidos por todo el mundo, necesitábamos mostrar la notificación de acuerdo con la zona horaria. El almacenamiento de la marca de tiempo en UTC cumplió muy bien nuestro propósito, sin contratiempos.

En su caso de uso, si no está almacenando la zona horaria del usuario en algún lugar, nunca podrá devolver con precisión los resultados de su búsqueda sin solicitar la entrada del usuario, a menos que comience a usar algún tipo de detección de ubicación como lo hace gmaps, pero eso no es ' t confiable. Por lo tanto, deberá solicitar la zona horaria cada vez para asegurarse de que el usuario sepa lo que está ingresando en el sitio web.

Si tiene información de zona horaria, toda la aplicación web debe ejecutarse con la configuración de zona horaria. Por lo tanto, cuando el usuario busque las 9:00, buscará con la zona horaria de Sydney. Por otro lado, si crea un evento mientras está sentado en Nueva York, creará un evento con la zona horaria de Sydney. Resolvemos estos casos mostrando siempre la zona horaria mientras mostramos las fechas.

¡Espero eso ayude! :)

Varun Achar
fuente
Creo que con la adición de un menú desplegable para las zonas horarias al buscar y crear eventos, este es el camino a seguir. (cuando necesito buscar el evento creado por un colega en Nueva York, no quiero hacer los cálculos yo mismo)
RasmusWL
Esta es una respuesta genial. ¿Existe alguna práctica recomendada sobre cómo almacenar la información de la zona horaria? Por ejemplo, ¿cuál sería mejor, 'PST' o 'América / Pacífico'? ¿Cómo podré convertir fácilmente una marca de tiempo en UTC a la zona horaria del usuario capturado? Se agradecería cualquier mejor práctica al respecto.
Patthebug
11
  1. UTC. Mantenlo simple.

  2. Utilice la zona horaria que sea más relevante para el usuario.

    Si sabe que el usuario va a estar o viajar a Sydney para el evento, entonces estará pensando en esa zona horaria cuando organice el transporte al evento. El hecho de que se encuentren actualmente en Nueva York es en gran medida irrelevante. Y, por supuesto, si su aplicación muestra fechas en una variedad de zonas horarias, siempre debería mostrar la zona horaria junto a la fecha, por ejemplo, 09:00 EST .

    Si no satura demasiado su interfaz, puede mostrar las fechas en la zona horaria del evento y la zona horaria local, por ejemplo, 2012-06-13 09:00 EST (2012-06-12 19:00 EDT) .

    Yo diría que la búsqueda es un problema similar, con una advertencia: podemos tolerar los falsos positivos (obteniendo un resultado que no esperábamos), pero no podemos soportar los falsos negativos (no obteniendo el resultado que esperábamos).

    Una vez más, me centraría en buscar la zona horaria más relevante para el usuario (por ejemplo, la zona horaria del evento) y dar prioridad a estos resultados en los resultados de búsqueda, pero también puede devolver eventos que coincidan en otras zonas horarias que sean relevantes para el usuario (por ejemplo, hora local). Si hace esto, debe mostrar la fecha del evento en la zona horaria coincidente, especialmente si resalta el texto coincidente.

Richard Poole
fuente
7

Aquí estoy dando sugerencias para la mejor usabilidad sin preocuparme mucho por la viabilidad de la implementación.
1. Para el primer número de almacenamiento de eventos en db, todos estarían de acuerdo en almacenarlo en UTC

2. Para brindar la mejor experiencia de usuario, guarde el historial de la zona horaria del usuario. Si pudiera guardar la marca de tiempo del cambio de zona horaria, aún mejor. Esto nos permitirá dar libertad al usuario para realizar consultas sin especificar la zona horaria de forma explícita cada vez.

Entonces, con estas características, veamos cómo se manejará la consulta de búsqueda de solo "9.00" de John:
Con las características mencionadas anteriormente, ahora sé que John ha estado en 2 zonas horarias hasta la fecha (u obtenga la lista de zonas horarias para el período mencionado). Así que convertiré las 9.00 de la zona horaria de Sydney a UTC, lanzaré una consulta. También convierta 9.00 de la zona horaria de NewYork a UTC, active una consulta. Como resultado, le mostraré 2 filas a John mostrando lo que hizo a las 9:00 en Sydney y a las 9:00 en Nueva York. La línea de Nueva York estará en blanco en este caso, pero creo que aún debería mostrarse al usuario, solo para informarle que también buscamos esta zona horaria.

3. ¿Cuál es una buena manera de pedirle al usuario una marca de tiempo que pueda incluir la zona horaria?

Si su zona horaria se modificó recientemente, cada vez que inicie sesión en la aplicación, debe recibir una notificación de que su zona horaria predeterminada se cambia a la zona horaria nativa.
Al crear un evento, digamos que el usuario selecciona la zona horaria del menú desplegable. No sobrecargue al usuario al ofrecer opciones de todas las zonas horarias del mundo. La primera opción del menú desplegable debe ser la zona horaria actual del dispositivo del usuario. después de esas zonas horarias de su historial de zonas horarias, luego UTC y luego las zonas horarias restantes que nunca ha usado hasta la fecha.

4.Cómo mostrar los resultados, si equipos de todo el mundo necesitan discutir el evento:

Me gustaría dividir este caso de uso entre el número de equipos 2 o más de 2.
Para solo 2 equipos, preferiría que cada equipo vea la marca de tiempo en su zona horaria local y en la zona horaria del otro equipo. (Yo personalmente prefiero hablar en la zona horaria de la persona en el otro extremo para su conveniencia mientras programo una reunión). Para más de 2 equipos, es mejor considerar una zona horaria más común, es decir, UTC. Entonces, en este caso, cada usuario debería ver la marca de tiempo en 2 zonas horarias, en UTC y en su zona horaria predeterminada.

Estas sugerencias se dan con la intención de que el usuario no necesite hacer ningún cálculo en su hora local, pero al mismo tiempo debería poder comunicarse con otros usuarios con fluidez en su zona horaria preferida.

Pranalee
fuente
2
+1 Esta es una idea muy interesante porque sé que el usuario ingresó a un evento a las 9:00 en Sidney, por lo que cuando el mismo usuario busca una hora (sin zona horaria explícita), debo asumir que quiere decir "dónde estaba esa vez "
Aaron Digulla
4

Ok, tengo un enfoque diferente al de otros:

En primer lugar, asumí algunas cosas de antemano.

La persona que está listando un evento tiene un teléfono inteligente (si es un navegador, no tengo que hacer estas suposiciones) con:

  1. GPS

  2. Capacidad HTML5.

  3. Capacidad de Javascript

¿Cómo debo guardar las marcas de tiempo en la base de datos?

Solución: Obviamente UTC , superpuse el procedimiento a continuación:

Paso 1. Utilice la geolocalización del usuario mediante la API de geolocalización

    window.onload = getMyLocation;

    function getMyLocation() {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(displayLocation);
        } else {
            alert("Oops, no geolocation support");
        }
    }

    function displayLocation(position) {
        var latitude = position.coords.latitude;
        var longitude = position.coords.longitude;
        var div = document.getElementById("location");
        div.innerHTML = "You are at Latitude: " + latitude + ", Longitude: " + longitude;
    }

Paso 2. Dé (Long, Lat) como argumentos a algunas de las api (Lat, Long) to TimeZone como la API de Yahoo (use Flag R para convertir la latitud en Timezone) para obtener la zona horaria de los usuarios.

=> La zona horaria del usuario se determina sin la entrada del usuario (estoy usando esto porque no se puede simplemente asumir que el usuario conoce la zona horaria del lugar en el que vive, supe mi zona horaria solo después de unos meses o algo en el lugar: P, ¡bastante tonto! )

La tabla de cada evento tiene Timezone, Eventy también puede tener. CityName Luego, cree otra tabla de base de datos con una clasificación basada en CityNames. Entonces aquí el usuario tendrá dos columnas

|---------------------------------------|
|_____NewYork________|______Sydney______|
|                    |                  |
|Event 1             |  Event 2         |
|____________________|__________________| 

Para UI

=> use la API de Google Calendar o algunas de las API de Calendar

Lecturas relacionadas:

  1. Determine la zona horaria a partir de la latitud / longitud sin utilizar servicios web como Geonames.org

  2. Búsqueda de zona horaria a partir de latitud y longitud

Sé que solo se trata de mostrar una idea de cómo resolver este problema. Pero vea qué tan precisa y liviana se vuelve para los usuarios cuando la zona horaria se determina mediante el uso de API de dispositivo

¡Espero eso ayude!

uday
fuente
4
Es bastante fácil encontrar la zona horaria de alguien sin geolocalización. new Date().getTimezoneOffset()lo da en minutos detrás de UTC.
Ry-
@minitech, eso es cierto, pero ¿qué pasa si el evento está sucediendo en NuevaYork y en algún lugar del sur donde es la misma zona horaria? Estoy usando la geolocalización para que pueda identificar la ciudad (incluso con precisión), la zona horaria en onehot y basar mi tabla de base de datos en ella. Quiero minimizar la entrada del usuario usando la API del dispositivo para aumentar la efectividad de la aplicación.
uday
¿Entonces? El tiempo será el mismo en ambos lugares, por lo que no hay problema. -1
Ry-
@minitech, puede ver este enlace sobre por qué recomiendo usar api de dispositivos que otros métodos. webdirections.org/sotmw2011
uday
2
De acuerdo, pero el problema aquí no es obtener la ciudad del usuario. Solo se trata de obtener la zona horaria. Usar una API de geolocalización que no funciona en todos los navegadores / computadoras, y luego redirigir a una API de calendario, es una mala manera de obtener la zona horaria de un usuario cuando está disponible en una línea de código.
Ry-
2

Para ese caso particular, me almacenar tanto la hora local y UTC. UTC es algo importante y se utiliza para sincronizar y convertir la hora a la zona horaria actual. Local se usa para búsquedas y para información adicional, como:

Tienes una reunión:

12:00 Monday (UTC)
9:00 Monday (Sydney, creation local time)
11:00 Monday (Zurich, local time)

o algo así. La otra forma es almacenar la zona horaria de creación y convertir en tiempo de ejecución (esto es particularmente mejor en caso de que el usuario cambie la hora de la reunión). De cualquier manera, la razón principal es poder restaurar el tiempo de creación original para que el usuario pueda consultarlo.

Petr Abdulin
fuente
2
  1. ¿Cómo debo guardar las marcas de tiempo en la base de datos?

En la creación del evento, almacenaría la hora UTC y la zona horaria local (también conocida como creation time zone). Usaría lo que almacené para convertir la hora UTC en hora local (también conocida como creation time) y almacenarla junto con la hora UTC y creation time zone.

NOTA: Puedo almacenar la hora local desde el principio, pero cuando el usuario busca un evento, espero que exista una conversión a la hora local. También espero que el servidor pueda detectar en qué zona horaria se encuentra el cliente.

  1. ¿Cómo debo presentarlos en la interfaz de usuario?

Cuando un usuario busca "9:00", yo buscaría eventos que incluyan "9:00" en UTC O creation time O en hora local. Para los resultados, mostraría una tabla de resultados en creation time(Esto está destinado a mostrar marcas de tiempo que pueden haber sido creadas en una zona horaria diferente, ya que asumimos que el usuario está buscando a qué hora creó un evento para donde sea que esté). y muestre una segunda tabla de resultados a continuación con resultados relacionados, tal vez con el encabezado "¿No es lo que está buscando? Ver resultados relacionados" (estos incluyen los resultados restantes de UTC y hora local).

En general, mostraría la hora UTC, la hora local creation time, y el creation time zone(es decir, la hora local y la zona horaria del evento donde se creó) ordenados por hora UTC, para que pueda ver qué evento viene primero, en caso de que haya dos diferentes Los eventos estaban programados para las 9:00 en dos zonas horarias diferentes.


fuente
1
+1 Me gusta la idea de mostrar todos los eventos en todas las zonas horarias donde coincide la hora local; No estoy satisfecho con SQL ( BETWEENcondiciones 24x ).
Aaron Digulla