Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

333
Visualizações
Change part of a timestamp (not relatively) in PostgreSQL

I saw similar questions here, e. g. "I want to change time from 13:00 to 17:00" and always answers were "use '13:00' + INTERVAL '4 hours'"

BUT, what I need is to SET the date_part value to existing date, without knowing the exact interval size, something opposite to date_part (extract) function.

For example:

-- 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)

Which result will be:

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

As you can see, this cannot be done with simple +/- INTERVAL expression.

Possible solution

What I've already found on SO is:

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)

But this variant does not preserve minutes and seconds.

Although, I can fix this issue, simply adding back minutes, seconds and microseconds of original timestamp:

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)

This will output:

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

And it solves the problem.

But honestly, I'm not very pleased by this solution. Maybe someone knows better variants?

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

The idea behind the below function is to clear the unit (subtract the corresponding interval) and add a given interval.

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
$$;

Check:

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)

Try it in db<>fiddle.

over 4 years ago · Santiago Trujillo Relatório

0

There's no function to set a specific part of a timestamp, but you can use date/time arithmetic to produce the result you want. For example:

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

Result:

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

See running example at DB Fiddle.

over 4 years ago · Santiago Trujillo Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda