Postgres ma kilka typów znaczników czasu:
sygnatura czasowa bez strefy czasowej - (najlepiej przechowywać znaczniki czasu UTC) Można ją znaleźć w pamięci masowej wielonarodowej bazy danych. Klient w tym przypadku zajmie się przesunięciem strefy czasowej dla każdego kraju.
timestamp with timezone - Przesunięcie strefy czasowej jest już uwzględnione w sygnaturze czasowej.
W niektórych przypadkach Twoja baza danych nie korzysta ze strefy czasowej, ale nadal musisz grupować rekordy pod kątem lokalnej strefy czasowej i czasu letniego (np. Https://www.timeanddate.com/time/zone/romania/bucharest )
Aby dodać strefę czasową, możesz skorzystać z tego przykładu i zastąpić przesunięcie strefy czasowej swoim.
"your_date_column" at time zone '+03'
Aby dodać przesunięcie czasu letniego +1 specyficzne dla czasu letniego, musisz sprawdzić, czy twój znacznik czasu przypada na letni czas letni. Ponieważ te przedziały zmieniają się co 1 lub 2 dni, użyję przybliżenia, które nie wpływa na zapisy na koniec miesiąca, więc w tym przypadku mogę zignorować dokładny interwał każdego roku.
Jeśli trzeba zbudować bardziej precyzyjne zapytanie, musisz dodać warunki, aby utworzyć więcej przypadków. Ale z grubsza będzie to działać dobrze przy dzieleniu danych na miesiąc według strefy czasowej i czasu letniego, gdy znajdziesz w swojej bazie danych znacznik czasu bez strefy czasowej:
SELECT
"id", "Product", "Sale",
date_trunc('month',
CASE WHEN
Extract(month from t."date") > 03 AND
Extract(day from t."date") > 26 AND
Extract(hour from t."date") > 3 AND
Extract(month from t."date") < 10 AND
Extract(day from t."date") < 29 AND
Extract(hour from t."date") < 4
THEN
t."date" at time zone '+03' -- Romania TimeZone offset + DST
ELSE
t."date" at time zone '+02' -- Romania TimeZone offset
END) as "date"
FROM
public."Table" AS t
WHERE 1=1
AND t."date" >= '01/07/2015 00:00:00'::TIMESTAMP WITHOUT TIME ZONE
AND t."date" < '01/07/2017 00:00:00'::TIMESTAMP WITHOUT TIME ZONE
GROUP BY date_trunc('month',
CASE WHEN
Extract(month from t."date") > 03 AND
Extract(day from t."date") > 26 AND
Extract(hour from t."date") > 3 AND
Extract(month from t."date") < 10 AND
Extract(day from t."date") < 29 AND
Extract(hour from t."date") < 4
THEN
t."date" at time zone '+03' -- Romania TimeZone offset + DST
ELSE
t."date" at time zone '+02' -- Romania TimeZone offset
END)