Saltar al contenido

Fecha de PostgreSQL () con zona horaria

Verificamos de forma profundamente cada secciones de nuestra página web con el objetivo de mostrarte siempre la información más veraz y actual.

Solución:

Básicamente lo que quieres es:

$ select starts_at AT TIME ZONE 'UTC' AT TIME ZONE 'US/Pacific' from schedules where id = 40

Obtuve la solución de este artículo a continuación, ¡que es directamente ORO! Explica muy claramente este problema no trivial, léalo si desea comprender mejor la administración de pstgrsql TZ.

Expresar marcas de tiempo de PostgreSQL sin zonas en la hora local

Aquí es donde está pasando. Primero debe saber que ‘la zona horaria PST está 8 horas por detrás de la zona horaria UTC, por lo que, por ejemplo, el 1 de enero de 2014 a las 4:30 p.m. PST (miércoles, 01 de enero de 2014 16:00:30 -0800) es equivalente al 2 de enero de 2014, 00:30 AM UTC (jueves, 02 de enero de 2014 00:00:30 + 0000). Cualquier momento después de las 4:00 pm en PST pasa al día siguiente, interpretado como UTC.

Además, como Erwin Brandstetter mencionó anteriormente, postresql tiene dos tipos de tipos de datos de marcas de tiempo, uno con una zona horaria y otro sin ella. Si sus marcas de tiempo incluyen una zona horaria, entonces un simple:

$ select starts_at AT TIME ZONE 'US/Pacific' from schedules where id = 40

trabajará. Sin embargo, si su marca de tiempo es sin zona horaria, la ejecución del comando anterior no funcionará, y PRIMERO debe convertir su marca de tiempo sin zona horaria en una marca de tiempo con una zona horaria, es decir, una zona horaria UTC, y SÓLO ENTONCES convertirla a su deseado ‘PST’ o ‘US / Pacífico ‘(que son lo mismo hasta algunos problemas del horario de verano. Creo que debería estar bien con cualquiera de ellos).

Permítanme demostrar con un ejemplo en el que creo una marca de tiempo sin zona horaria. Supongamos por conveniencia que nuestra zona horaria local es de hecho ‘PST’ (si no lo fuera, se vuelve un poco más complicado, lo cual es innecesario para el propósito de esta explicación).

Di que tengo:

$ select timestamp '2014-01-2 00:30:00' AS a, timestamp '2014-01-2 00:30:00' AT TIME ZONE 'UTC' AS b,  timestamp '2014-01-2 00:30:00' AT TIME ZONE 'UTC' AT TIME ZONE 'PST' AS c, timestamp '2014-01-2 00:30:00' AT TIME ZONE 'PST' AS d

Esto producirá:

"a"=>"2014-01-02 00:30:00"   (This is the timezoneless timestamp)
"b"=>"2014-01-02 00:30:00+00" (This is the UTC TZ timestamp, note that up to a timezone, it is equivalent to the timezoneless one)
"c"=>"2014-01-01 16:30:00" (This is the correct 'PST' TZ conversion of the UTC timezone, if you read the documentation postgresql will not print the actual TZ for this conversion)
"d"=>"2014-01-02 08:30:00+00"

La última marca de tiempo es la razón de toda la confusión con respecto a la conversión de la marca de tiempo sin zona horaria de UTC a ‘PST’ en postgresql. Cuando escribimos:

timestamp '2014-01-2 00:30:00' AT TIME ZONE 'PST' AS d

Estamos tomando una marca de tiempo sin zona horaria e intentamos convertirla a ‘PST TZ (asumimos indirectamente que postgresql entenderá que queremos que convierta la marca de tiempo de una UTC TZ, ¡pero postresql tiene sus propios planes!). En la práctica, lo que hace postgresql es que toma la marca de tiempo sin zona horaria (‘2014-01-2 00:30:00) y la trata como si YA FUERA una marca de tiempo’ PST ‘TZ (es decir: 2014-01-2 00:30 : 00-0800) y lo convierte a la zona horaria UTC. ¡Así que en realidad lo adelanta 8 horas en lugar de retroceder! Así obtenemos (2014-01-02 08: 30: 00 + 00).

De todos modos, este último comportamiento (poco intuitivo) es la causa de toda confusión. Lea el artículo si desea una explicación más completa, en realidad obtuve resultados que son un poco diferentes a los de esta última parte, pero la idea general es la misma.

No veo el exacto tipo de starts_at en tu pregunta. Realmente debería incluir esta información, es la key a la solución. Tendré que adivinar.

Básicamente, PostgreSQL siempre almacena el valor de hora UTC para el tipo timestamp with time zone internamente. Solo la pantalla varía con su timezone configuración. El efecto de la AT TIME ZONE La construcción también cambia con el tipo de datos subyacente. Más detalles:

  • Ignorar las zonas horarias por completo en Rails y PostgreSQL

Si extrae un date de tipo timestamp [without time zone], obtiene la fecha de la zona horaria actual. El día en la salida será el mismo que en la visualización del timestamp valor.

Si extrae un date de tipo timestamp with time zone (timestamptz para abreviar), el desplazamiento de zona horaria se “aplica” primero. Aún obtiene la fecha de la zona horaria actual, que coincide con la monitor de la marca de tiempo. El mismo punto en el tiempo se traduce al día siguiente en algunas partes de Europa, cuando son más de las 4 pm en California, por ejemplo. Para obtener la fecha de una determinada zona horaria, aplique AT TIME ZONE primero.

Por lo tanto, lo que describe al principio de la pregunta contradice su ejemplo.

Dado que starts_at es un timestamp [without time zone] y la hora de su servidor se establece en la hora local. Prueba con:

SELECT now();

¿Muestra la misma hora que un reloj en tu pared? Si es así (y el servidor de base de datos se está ejecutando con la hora correcta), timezone la configuración de su sesión actual coincide con su zona horaria local. Si la respuesta es no, es posible que desee visitar el entorno de timezone en tus postgresql.conf o su cliente para la sesión. Detalles en el manual.

Tenga en cuenta que el timezone offset utilizó lo contrario firmar de lo que se muestra en los literales de marca de tiempo. Ver:

  • Manejo peculiar de la zona horaria en una base de datos de Postgres

Para obtener su fecha local de starts_at solo

SELECT starts_at::date

Tantamount a:

SELECT date(starts_at)

Por cierto, su hora local es UTC-7 en este momento, no UTC-8, porque el horario de verano está en vigor (no entre las ideas más brillantes de la raza humana).

La Hora estándar del Pacífico (PST) es normalmente 8 horas “antes” (mayor timestamp valor) que UTC (zona horaria universal), pero durante los períodos de ahorro de luz diurna (como ahora) puede ser de 7 horas. Es por eso timestamptz se muestra como 2012-06-21 02:00:00-07 en tu ejemplo. El constructo AT TIME ZONE 'PST' tiene en cuenta el horario de verano. Estas dos expresiones producen resultados diferentes (una en invierno, otra en verano) y pueden dar lugar a fechas diferentes cuando se emiten:

SELECT '2012-06-21 01:00:00'::timestamp AT TIME ZONE 'PST'
     , '2012-12-21 01:00:00'::timestamp AT TIME ZONE 'PST'

Sé que este es antiguo, pero es posible que desees considerar el uso de AT TIME ZONE “EE. UU./Pacífico” al transmitir para evitar problemas de PST / PDT. Entonces

SELECT starts_at::TIMESTAMPTZ AT TIME ZONE "US/Pacific" 
  FROM schedules 
 WHERE ID = '40';

Si eres capaz, tienes la opción de dejar una noticia acerca de qué le añadirías a este post.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *