Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

335
Vistas
Cambiar parte de una marca de tiempo (no relativamente) en PostgreSQL

Vi preguntas similares aquí, por ejemplo, "Quiero cambiar la hora de 13:00 a 17:00" y las respuestas siempre fueron "usar '13:00' + INTERVAL '4 hours' "

PERO, lo que necesito es ESTABLECER el valor de date_part en la fecha existente, sin saber el tamaño exacto del intervalo, algo opuesto a date_part ( extract ).

Por ejemplo:

 -- NOT A REAL FUNCTION SELECT date_set('hour', date, 15) FROM (VALUES ('2021-10-23 13:14:43'::timestamp), ('2020-11-02 10:00:34')) as dates (date)

Cual resultado sera:

 2021-10-23 15:14:43 2020-11-02 15:00:34

Como puede ver, esto no se puede hacer con una simple expresión +/- INTERVAL .

Solución posible

Lo que ya he encontrado en SO es:

 SELECT date_trunc('day', date) + INTERVAL '15 hour' FROM (VALUES ('2021-10-23 13:14:43'), ('2020-11-02 10:00:34')) as dates (date)

Pero esta variante no conserva minutos y segundos.

Aunque puedo solucionar este problema, simplemente agregando minutos, segundos y microsegundos de la marca de tiempo original:

 SELECT date_trunc('day', date) + INTERVAL '15 hour' + (extract(minute from date) || ' minutes')::interval + (extract(microsecond from date) || ' microseconds')::interval FROM (VALUES ('2021-10-23 13:14:43.001240'::timestamp), ('2020-11-02 10:00:34.000001')) as dates (date)

Esto generará:

 2021-10-23 15:14:43.001240 2020-11-02 15:00:34.000001

Y resuelve el problema.

Pero, sinceramente, no estoy muy satisfecho con esta solución. ¿Quizás alguien conoce mejores variantes?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

La idea detrás de la siguiente función es borrar la unidad (restar el intervalo correspondiente) y agregar un intervalo dado.

 create or replace function timestamp_set(unit text, tstamp timestamp, num int) returns timestamp language sql immutable as $$ select tstamp+ (num- date_part(unit, tstamp))* format('1 %s', unit)::interval $$;

Cheque:

 select date, timestamp_set('hour', date, 15) as hour_15, timestamp_set('min', date, 33) as min_33, timestamp_set('year', date, 2022) as year_2022 from ( values ('2021-10-23 13:14:43'::timestamp), ('2020-11-02 10:00:34') ) as dates (date) date | hour_15 | min_33 | year_2022 ---------------------+---------------------+---------------------+--------------------- 2021-10-23 13:14:43 | 2021-10-23 15:14:43 | 2021-10-23 13:33:43 | 2022-10-23 13:14:43 2020-11-02 10:00:34 | 2020-11-02 15:00:34 | 2020-11-02 10:33:34 | 2022-11-02 10:00:34 (2 rows)

Pruébalo en db<>fiddle.

over 4 years ago · Santiago Trujillo Denunciar

0

No hay una función para establecer una parte específica de una marca de tiempo, pero puede usar la aritmética de fecha/hora para producir el resultado que desea. Por ejemplo:

 select d + (15 - extract(hour from d)) * interval '1 hour' from dates

Resultado:

 ?column? ------------------------ 2021-10-23T15:14:43.000Z 2020-11-02T15:00:34.000Z

Ver ejemplo de ejecución en DB Fiddle .

over 4 years ago · Santiago Trujillo Denunciar

0

SELECT to_timestamp(to_char(ts, 'YYYY-MM-DD 15:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') as fixed_time FROM (VALUES ('2021-10-23 13:14:43'::timestamp), ('2020-11-02 10:00:34'::timestamp)) as dates (ts); 2021-10-23 15:14:43.000000 +00:00 2020-11-02 15:00:34.000000 +00:00
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda