How to get the start date of ISOYEAR in postgresql?
For example, i have a date 2012-01-01, isoyear is 2011 and it isoyear starts at 2011-01-03 and ends at 2012-01-01.
There is different ways to get isoyear, but i have no idea how to get date that iso year begins.
select extract(isoyear from '01.01.2012'::date)
select to_char('01.01.2012'::date,'IYYY')
Ask it to convert the first "ISO day" of the "ISO year":
=> SELECT to_date('2011-0001', 'IYYY-IDDD');
to_date
------------
2011-01-03
Related
I have some date time strings with day first. When I try to convert to TIMESTAMPTZ the month seems to be ignored.
Example
TO_TIMESTAMPTZ('01/07/2020 04:00', 'DD/MM/YYYY HH:MM')
Returns
2020-01-01T04:00:00.000+00:00
I'm looking for 1st July but get 1st January (not even 7th January!)
The pattern for minutes is MI, not MM (see documentation):
dbadmin=> select TO_TIMESTAMP_TZ('01/07/2020 04:00', 'DD/MM/YYYY HH:MI');
TO_TIMESTAMP_TZ
------------------------
2020-07-01 04:00:00+02
I have a DateTime column (activation_dt) in DB2 table and I want to add 1 day to the date part and my output should be "date 00:00:00".
For example:
How it is - 5/9/2001 03:00:00
how it should be - 5/10/2001 00:00:00
I tried using Concat function but is not working. Date part I am doing as "date(activation_dt +1 day) as new_dt"
Please help how should I achieve this is DB2.
You could cast it to a DATE, then TIMESTAMP. Here is the invers, try out the individual parts.
values date(timestamp(current date))
BTW: What is CURRENT TIMEZONE?
Try this
VALUES date_trunc('DAY', CURRENT TIMESTAMP + 1 DAY)
it will always return the next day 00:00:00 - use activation_dt instead of current timestamp
Can anyone help me to find the specific week day of the month in postgresql... like 1st and 3rd week sunday/monday or 2nd and 4th week wednesday
First off contrary to initial expectations working with dates is complex, sometime extremely so. The combination of week numbers and days the week fall into the latter category.
The problem stems from the 2 ISO definitions:
All weeks start on Monday and are 7 days long.
The first week of the year is the week containing 4-Jan.
This dooms any effort (at least any reasonable simple onc) to failure. While an admirable effort I'll use #Abelisto suggestion as a sample. See Fiddle. I've changed that just enough to use multiple parameters, while for most months it's correct but look at 30,31-Jan-2019 and Jan-2021.
The problem with the first being while the ISO week is perfectly consistent the calendar is not. This results that the first week of a given month be the same as the last week of the previous month, and the reverse.
While this can usually be worked around by itself not so when combined with the other. As a result of each being 7 days long and the 1st week of the year containing 4-Jan gives rise to the larger problem. The last few days of Dec maybe in the 1st week of the next year. Also the first days of Jan can be in the 52( or 53) week of the prior year (see 2nd query in fiddle). Is there a solution? I'm sure there is somewhere out there. I just don't have it. At least with the Extract function.
So how about this specific issue: Well basically it comes down to getting the last day of the previous month, then finding the next DOW (Sunday or Monday) as needed. Now coming from a Oracle back ground I'd just use the NEXT_DAY function which would do just that for me. Unfortunately Postgres does not provide that useful function. But you can roll your own. Below I provide a a couple functions I wrote to do this functionality in Postgres. It consists of 2 Postgres SQL functions:
- utl_dates_first_dow_of_month(). It takes 2 parameters, the target Day-Of-Week (DOW) as the first 3 characters of the day name (case insensitive) and a date in the desired month. It returns the DATE which is the first occurrence of the requested DOW.
- utl_dates_next_dow(). It takes the same 2 parameters and returns the next calendar date of the specified DOW from the from the specified date. If the date specified fall on the requested DOW the routine DOES NOT return the specified date. Function is actually used by the first.
Fortunately the routines are shorter than the description.
create or replace function utl_dates_next_dow(dow_in text, date_in date)
returns date
language sql
immutable strict
as $$
-- Given a DOW and a date return the calendar date for the next occurrence of DOW
with dy as (select string_to_array('mon,tue,wed,thu,fri,sat,sun', ',') dl)
, dn as (select array_position(dl, (substring(to_char(date_in, 'day'),1,3))) fn
, array_position(dl, lower(substring(dow_in,1,3))) dn
from dy
)
select case when dn <= fn
then (date_in + (dn+7-fn) * interval '1 day')::date
else (date_in + (dn-fn) * interval '1 day')::date
end
from dn;
$$;
create or replace function utl_dates_first_dow_of_month(dow_in text, date_in date)
returns date
language sql
immutable strict
as $$
-- Given a DOW and a Date return the calendar date of the first specified dow in which the specified date falls.
select utl_dates_next_dow(dow_in, (date_trunc('month', date_in) - interval '1 day')::date);
$$;
Now with that out out of the way on the the issue at hand. As Abelisto, and others, indicate the request is ambiguous. There is no such thing as 1st or 3rd Sunday/Monday. Do you want the 1st and 3rd Sunday and the 1st and 3rd Monday of the month? Do you want
Do you want the 1st and 3rd Sunday of the month and the Monday following each respectively. Do you want the Sunday and Monday for the 1st and 3rd week on the month (If so Monday would always be the earlier date, see definition 1 above)? Please try to be more specific with your questions. And include test data - as text no images - and the expected results from that data. The solutions are however just slight modifications of each other. (No solution for the 3rd listed possibility.)
For the case of 1st and 3rd Sunday and the 1st and 3rd Monday:
with parms (dt) as (values ( date '2020-04-01'), (date '2020-06-01') )
, base_dates( fsun, fmon) as
( select utl_dates_first_dow_of_month('Sun',dt)
, utl_dates_first_dow_of_month('Mon',dt)
from parms
)
select '1st & 3rd Sunday and 1st & 3rd Monday'
, fsun "1st Sunday"
, (fsun+interval '14 days')::date "3rd Sunday"
, fmon "1st Monday"
, (fmon+interval '14 days')::date "3rd Monday"
from base_dates;
For the 1st and 3rd Sunday of the month and the Monday following:
with parms (dt) as (values ( date '2020-04-01'), (date '2020-06-01') )
, base_dates( fsun, fmon) as
( select utl_dates_first_dow_of_month('Sun',dt)
, (utl_dates_first_dow_of_month('Sun',dt)+interval '1 day')::date
from parms
)
select '1st & 3rd Sunday and Monday Following '
, fsun "1st Sunday"
, fmon "1st Monday"
, (fsun+interval '14 days')::date "3rd Sunday"
, (fmon+interval '14 days')::date "3rd Monday"
from base_dates;
select * from
(
select dow, i, row_number() over(partition by dow order by i) as rnk from
(
select
extract(dow from i::date) as dow,
i::date
from generate_series('2022-10-01'::date,'2022-10-31'::date,interval '1 Day') i
) tmp where dow = 1
)tmp_out where rnk = 3;
I have a date column 'visit_date' of the format '2018-10-04'.
I would need to derive "Week-Start to Week-End" column of format
"Oct 1 to Oct 7" or "1st Oct to 7th Oct", which means
I need to concatenate 2 dates - Week Begin and Week End post which I need to exclude the "Year" part of the dates.
Saw an answer here. It is partially suiting my requirement, where the answer would be "2018-09-03 to 2018-09-09"
SELECT date_trunc('week', visit_date)::date || ' -> '|| (date_trunc('week', visit_date)+ '6 days'::interval)::date as WeekPeriod
If you just need to format the date, to_char is what you need (https://www.postgresql.org/docs/current/static/functions-formatting.html):
SELECT to_char(your_date, 'Mon FMDD') --> Oct 1
SELECT to_char(your_date, 'FMDDth Mon') --> 1st Oct
demo: db<>fiddle
Mon gives the three lettered month
DD gives the day
FM prefix removes leading zeros
th suppif adds the "st", "nd", "rd", "th" ending
select to_char(date_trunc('week', visit_date),'YYYY-MM-DD')||'->'||
to_char((date_trunc('week', visit_date)+ '6 days'::interval),'YYYY-MM-DD') weekPeriod
The key here is the to_char, which allows custom date formats.
There is generally no need to store this type of data as it can be queried in the future the same way it was inserted above, and if you DO need to do queries on this information, it'd be better to store them as dates and not strings, however, the query above will fill the need you described.
I need to change the week start date from Monday to Saturday in PostgreSQL. I have tried SET DATEFIRST 6; but it doesn't work in PostgreSQL. Please suggest solution for this.
It appears that DATEFIRST is a thing in Microsoft Transact-SQL.
I don't believe Postgres has any exact equivalent, but you should be able to approximate it.
Postgres supports extracting various parts of a TIMESTAMP via the EXTRACT function. For your purposes, you would want to use either DOW or ISODOW.
DOW numbers Sunday (0) through Saturday (6), while ISODOW, which adheres to the ISO 8601 standard, numbers Monday (1) through Sunday (7).
From the Postgres doc:
This:
SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-18 20:38:40');
Returns 0, while this:
SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40');
Returns 7.
So you would use a version of EXTRACT in your queries to get the day of the week number. If you're going to use it in many queries, I would recommend creating a function which would centralize the query in one spot, and return the number transposed as you would like such that it started on Saturday (the transposition would vary depending on which numbering method you used in EXTRACT). Then you could simply call that function in any SELECT and it would return the transposed number.
You can just add +x, where x is the offset between postgres dow and what you want to achieve.
For example:
You want Sunday to be the first day of the week. 2018-06-03 is a Sunday and you want to extract the dow of it:
SELECT EXTRACT(DOW FROM DATE '2018-06-03')+1;
returns 1
That is probably the reason why postgres dow yields 0 for Sunday. Would it be 7, then
SELECT EXTRACT(DOW FROM DATE '2018-06-03')+1;
would return 8.