Zonas horarias y localización

Actualmente estoy almacenando todos los tiempos en UTC, para facilitar las cosas cuando comienzo a poner en línea múltiples sitios y servidores.

El problema surge cuando se traducen objetos de date y date y datetime en cadenas en mis plantillas y cuando se acepta la entrada del usuario. 6:00 PM UTC no significa mucho para alguien que está en PST. Del mismo modo, pedir a los usuarios que ingresen los horarios en UTC es pedir un desastre.

¿Cómo puedo traducir correctamente estos valores de una manera inteligente y no propensa a errores? ¿Hay una manera en que pueda determinar a partir de la solicitud HTTP en qué zona horaria está un usuario? Realmente necesito una forma de determinar la zona horaria del usuario con el menor esfuerzo posible.

El problema de confiar en el cliente para que se informe a sí mismo de su zona horaria es que siempre hay una posibilidad (lo que es una posibilidad discutible) de que lo que realmente obtendrá es un desplazamiento UTC . Si obtiene un desplazamiento UTC, su lógica funcionará bien la mayor parte del tiempo, pero en realidad solo se aplicará a las marcas de tiempo exactas producidas por el cliente. Cualquier hora pasada o futura puede tener un desplazamiento UTC diferente, y eso no se puede predecir sin una base de datos de zona horaria adecuada. Cerca del límite de ahorro de luz diurna, el uso de compensaciones UTC puede producir resultados catastróficamente erróneos.

Además de eso, algunos usuarios que no saben leer y escribir (es decir, la abuela) pueden no saber cómo configurar la zona horaria de su sistema local; o los usuarios en sesiones tunelizadas o máquinas virtuales pueden tener una zona horaria “local” que no está configurada para su preferencia real.

Adivinar la zona horaria política del cliente en base a lo que sabe sobre ese cliente (IP, etc.) puede ser incorrecto y puede ser bastante molesto si no hay forma de que el usuario anule la suposición. Pero para los usuarios anónimos o para el registro de nuevos usuarios, no veo nada de malo en utilizar un método como una suposición inicial, siempre y cuando le dé al usuario alguna forma de cambiarlo si está mal.

Mi recomendación sería específicamente:

  • Incluya la zona horaria de Olson como parte de cualquier perfil de usuario. Las zonas horarias se pueden consultar por país, y esto debería hacer que la selección del usuario de su zona horaria sea relativamente sencilla. Dele al 0.01% de usuarios que les importa la opción de UTC directo también 🙂
  • Si completa el valor predeterminado en el perfil de usuario con una suposición basada en IP, tendrá razón la mayor parte del tiempo si utiliza un buen servicio de búsqueda. Pero permite al usuario cambiarlo si está mal.
  • Para usuarios anónimos, proporcione algún tipo de widget en cualquier página que muestre o ingrese las horas locales, que les permita seleccionar su zona horaria de Olson, de la misma manera que para un perfil de usuario. Almacena el valor que elijan en una cookie. Predeterminado a UTC o a un valor estimado como el anterior.

Al implementar una aplicación basada en web que necesitaba mostrar marcas de tiempo en tiempos localizados, descubrí que no todos los clientes traducen UTC a las horas locales correctamente para fechas pasadas y futuras. Tuve que realizar todas las conversiones en el lado del servidor. Esto puede requerir un servicio web que toma una hora local y una zona horaria de Olson y devuelve una hora UTC.

Lo he hecho así. Es posible que deba instalar fácilmente pytz para los objetos de la zona horaria.

 import pytz import time import datetime d = time.time() print datetime.datetime.fromtimestamp(d, pytz.timezone('US/Eastern')) print datetime.datetime.fromtimestamp(d, pytz.timezone('US/Central')) print datetime.datetime.fromtimestamp(d, pytz.timezone('US/Mountain')) print datetime.datetime.fromtimestamp(d, pytz.timezone('US/Pacific')) 

La variable d aquí es almacenar el tiempo UTC como una marca de tiempo de Unix.

No se puede obtener de forma confiable la zona horaria de un usuario de los encabezados de solicitud. Es por eso que la mayoría de los sitios web les piden a los usuarios que establezcan su zona horaria en la configuración del perfil. Sin embargo, puede utilizar varios trucos para tratar de conseguir. Un truco es usar la API de IP a ubicación de Google para averiguar de dónde viene el usuario y luego tratar de adivinar la zona horaria desde la ubicación geográfica. Esto tampoco es 100% confiable, pero lo acercará a la verdad.

me di cuenta de que esto ya se ha preguntado aquí al menos una vez: obtener la zona horaria del usuario

Yo no haría la geolocalización ip. Puede ser muy impreciso, especialmente los servicios gratuitos. Solo pregunte al usuario por el código postal o el estado, y guárdelo en una cookie.

Puede, usando javascript (que conoce la hora local), cambiar la hora ingresada por el usuario a UTC antes de enviar los datos a su servidor. Luego, envíe UTC hacia abajo en un formato tal que javascript pueda convertirlo de UTC a la hora local.

Por ejemplo, una fecha a UTC para ser enviada al servidor:

 (new Date("November 11, 2011 23:13:42")).toUTCString() 

Y UTC a hora local, para renderizar:

 (new Date("October 17, 1986 15:29:13 UTC")).toLocaleString()