Ruben:

On Wed, 2 Nov 2022 at 07:10, Ruben Fitó <r.f...@ubiquat.com> wrote:
> Nos encontramos con que nuestro aplicativo necesita encontrar unos registros 
> en una tabla 1 hora antes hasta el momento actual.
> Todo funciona perfectamente hasta que tenemos cambio de horario en España.
> En concreto, este último sábado hemos pasado de las 3 de la madrugada a las 2.

Precision camarada, si no me equivoco mucho es el Domingo cuando
cambiamos de hora ( y lo comento porque decir el sabado, en general
usar el dia anterior para eventos que ocurren de ma o meno 0 a 6 es
tradicionalmente un indicador de poco habito de trabajar con TS ).

> Con este cambio de horario, no encontramos los registros de 1h antes ya que 
> se encuentran en el "Futuro" porque la columna de búsqueda no tiene TIME ZONE.
> ¿Conocen alguna manera de solucionar este problema sin modificar el tipo de 
> dato?
Hombre, con esas restricciones y dado
> PD: El modelo de la base de datos no depende de nosotros.
Salvo que tengas alguna columna en la que insertar el DST ( o un bit
para indicarlo haciendo trampas en alguna otra, yo p.e. he usado el
bit de signo de una duracion para distinguirlos, complica el codigo
pero funciona ) el problema no tiene solución, ya que puedes generar
registros exactamente iguales antes y despues.

Por cierto, tu problema no es que la columna no tenga time zone. Las
columnas de timestamp with time zone NO tienen tampoco el timezone
dentro, de hecho tienen el mismo formato, tu problema es que
probablemente estais haciendo una conversion irreversible de tstz a
tsntz ( p.e. no especificando la zona y fiandose de la de la sesion
y/o usando una zona con DST ), si la hicierais con un isomorfismo (
p.e. usando "at timezone utc" como conversion ) no tendriais ese
problema.


SALVO que puedas insertar tu los valores, en ese caso la solucion es
trivial, fija la timezone en la que guardas A UNA QUE NO TENGA DST (
yo recomendaria UTC, porque ahi unas cuantas mas que no lo tienen pero
no sabes si lo tendran, aunque es bastante seguro apostar porque los
paises sin verano no van a tener horario de verano, o te la puedes
definir tu, como 'EST-1', p.e. ) ( o sea insertar $TSTZ at time zone
utc" ). Esto te quita problemas, pero es mas que posible que tengas
que tocar ( fijate que en los queries tendras que hacer lo mismo, si
no lo estas haciendo ya, usar now at... ).



Un ejemplo:
s=> set time zone 'UTC';
SET
s=> select tstz, tstz at time zone 'UTC' as tsntz from (values(now()),
('2022-10-30 02:30:00+01'), ('2022-10-30 02:30:00+02'),('2022-11-2
08:00:00')) as v(tstz);
             tstz              |           tsntz
-------------------------------+----------------------------
 2022-11-02 08:38:40.863884+00 | 2022-11-02 08:38:40.863884
 2022-10-30 01:30:00+00        | 2022-10-30 01:30:00
 2022-10-30 00:30:00+00        | 2022-10-30 00:30:00
 2022-11-02 08:00:00+00        | 2022-11-02 08:00:00
(4 rows)

s=> set time zone 'Europe/Madrid';
SET
s=> select tstz, tstz at time zone 'UTC' as tsntz from (values(now()),
('2022-10-30 02:30:00+01'), ('2022-10-30 02:30:00+02'),('2022-11-2
08:00:00')) as v(tstz);
             tstz              |           tsntz
-------------------------------+----------------------------
 2022-11-02 09:38:58.903789+01 | 2022-11-02 08:38:58.903789
 2022-10-30 02:30:00+01        | 2022-10-30 01:30:00
 2022-10-30 02:30:00+02        | 2022-10-30 00:30:00
 2022-11-02 08:00:00+01        | 2022-11-02 07:00:00
(4 rows)

s=> set time zone 'America/New_York';
SET
s=> select tstz, tstz at time zone 'UTC' as tsntz from (values(now()),
('2022-10-30 02:30:00+01'), ('2022-10-30 02:30:00+02'),('2022-11-2
08:00:00')) as v(tstz);
             tstz              |           tsntz
-------------------------------+----------------------------
 2022-11-02 04:39:34.862039-04 | 2022-11-02 08:39:34.862039
 2022-10-29 21:30:00-04        | 2022-10-30 01:30:00
 2022-10-29 20:30:00-04        | 2022-10-30 00:30:00
 2022-11-02 08:00:00-04        | 2022-11-02 12:00:00
(4 rows)

Ahi puedes ver que now() y los timestamps insertados con origen
implicito son constantes ( now() no, pero se entiende lo que quiero
decir ) en la columna de tsntz ( porque tienen timezone explicito ).
La ultima columna sin embargo es "constante" en tstz pero salata en
tsntz ( porque no le puse zona en la entrada ).

Yo tengo problemas similares con los CDRs que nos pasan de una
compañia innombrable porque el formato es sin zona horaria, pero el
offset horario no esta fijado, y cuando no pasas explicitamente el
offset ( QUE NO LA ZONA, '2022-10-30 02:30:00' timestamp without time
zone at time zone 'Europe/Madrid' es ambiguo, la conversion en Pg no
lo es ( porque tiene una regla de eleccion. descrita, si no me falla
la memoria, en el apendice B2 ), pero la expresion lo es ). En ese
caso tengo algo de suerte porque suelen venir ordenados y puedo
parchear al importar.

En definitiva, tu problema no es por el postgres, pero tienes espacio
para arreglarlo sin tocar la BD ( otra cosa es que tengas, que
probablemente tendras, otras restricciones que no nos has contado ).

Saludos.


   Francisco Olarte.


Reply via email to