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.