mexico - timezone utc php
Tratando con husos horarios en PHP (4)
Podría intentar forzar a MySQL a usar UTC en todas partes usando SET time_zone
.
Lamentablemente, no recibí ninguna respuesta para Strtotime / UNIX_TIMESTAMP, de hecho, tengo el mismo problema con Postgres.
Algunos problemas con las zonas horarias en PHP han estado en mi mente por un tiempo, y me preguntaba si hay mejores formas de manejarlo que lo que estoy haciendo actualmente.
Todos los problemas giran en torno al reformado de las fechas almacenadas de la base de datos:
Cuando se trata de un sitio que tiene que admitir varias zonas horarias (para usuarios), para normalizar la zona horaria fuera de las marcas de tiempo almacenadas siempre la almaceno con la zona horaria del servidor utilizando el atributo CURRENT_TIMESTAMP
o la función NOW()
.
De esta forma, no tengo que considerar qué zona horaria se estableció para PHP cuando se ingresó la marca de tiempo (ya que las funciones de hora de PHP tienen en cuenta la zona horaria). Para cada usuario, de acuerdo con su preferencia, configuré la zona horaria en algún lugar de mi archivo bootstrap usando:
date_default_timezone_set($timezone);
Cuando estoy buscando formatear fechas con la función php date()
, debe tener lugar alguna forma de conversión, ya que MySQL actualmente almacena la marca de tiempo en el formato Ymd H:i:s
. Sin tener en cuenta la zona horaria, simplemente podría ejecutar:
$date = date($format,strtotime($dbTimestamp));
El problema con esto es que date()
y strtotime()
son funciones conscientes de la zona horaria, lo que significa que si la zona horaria de PHP se configura de manera diferente a la zona horaria del servidor, la compensación de la zona horaria se aplicará dos veces (en lugar de una vez).
Para tratar con esto, normalmente UNIX_TIMESTAMP()
las marcas de tiempo de MySQL usando la función UNIX_TIMESTAMP()
que no UNIX_TIMESTAMP()
la zona horaria, lo que me permite aplicarle date()
directamente, aplicando así el desplazamiento de la zona horaria solo una vez.
Realmente no me gusta este ''hack'' porque ya no puedo recuperar esas columnas como lo haría normalmente, o uso *
para buscar todas las columnas (a veces simplifica las consultas). Además, a veces simplemente no es una opción utilizar UNIX_TIMESTAMP()
(especialmente cuando se usa con paquetes de código abierto sin mucha abstracción para la composición de consultas).
Otro problema es cuando se almacena la marca de tiempo, cuando el uso de CURRENT_TIMESTAMP
o NOW()
no es una opción: el almacenamiento de una marca de tiempo generada por PHP lo almacenará con el desplazamiento de la zona horaria que me gustaría evitar.
Probablemente me esté perdiendo algo realmente básico aquí, pero hasta ahora no he podido encontrar una solución genérica para manejar esos problemas, así que estoy obligado a tratarlos caso por caso. Tus pensamientos son bienvenidos
Hace unos meses, pasamos un tiempo pensando en esto. La técnica con la que terminamos es bastante simple:
- Almacena las fechas en GMT / UTC (por ejemplo, 0 timezone offset).
- Aplique la compensación actual de la zona horaria del usuario después de la recuperación de la base de datos (por ejemplo, antes de mostrarla al usuario o cuando lo desee).
Usamos el formato de marcas de tiempo de Unix. Pero eso no importa.
Desde PHP 5.2, puede usar DateTime, lo que facilita el trabajo con zonas horarias:
$datetime = new DateTime($dbTimestamp, $timezone);
echo $datetime->format(''Y-m-d H:i:s'');
$datetime->setTimezone(new DateTimeZone(''Pacific/Nauru''));
echo $datetime->format(''Y-m-d H:i:s'');
No encontré ninguna solución elegante en línea, así que he creado una secuencia de comandos del generador de selección HTML de Timezone y aquí está la salida directamente. Es algo como esto:
<select name="timezone" id="timezone">
<optgroup label="UTC -11:00">
<option value="Pacific/Midway">UTC -11:00 Midway</option>
<option value="Pacific/Niue">UTC -11:00 Niue</option>
<option value="Pacific/Pago_Pago">UTC -11:00 Pago_Pago</option>
</optgroup>
<optgroup label="UTC -10:00">
<option value="America/Adak">UTC -10:00 Adak</option>
<option value="Pacific/Honolulu">UTC -10:00 Honolulu</option>
<option value="Pacific/Johnston">UTC -10:00 Johnston</option>
<option value="Pacific/Rarotonga">UTC -10:00 Rarotonga</option>
<option value="Pacific/Tahiti">UTC -10:00 Tahiti</option>
</optgroup>
. . . . . . . . . . . . . .
<optgroup label="UTC +13:00">
<option value="Pacific/Apia">UTC +13:00 Apia</option>
<option value="Pacific/Enderbury">UTC +13:00 Enderbury</option>
<option value="Pacific/Fakaofo">UTC +13:00 Fakaofo</option>
<option value="Pacific/Tongatapu">UTC +13:00 Tongatapu</option>
</optgroup>
<optgroup label="UTC +14:00">
<option value="Pacific/Kiritimati">UTC +14:00 Kiritimati</option>
</optgroup>
</select>
¡Disfrutar!