convert numeric week of year to a date (yyyy-mm-dd) in hiveql - date

It is easy enough to extract a week value from a date in hiveql:
select date_format('2020-10-18','w');
Is there a function for reversing this process: extracting the end date when provided a year and week number?

To get accurate date you need to provide also week day along with year and week number in a year.
select date_format('2020-10-18','w'), from_unixtime(unix_timestamp('2020, 43, 7', 'yyyy, w, u'), 'yyyy-MM-dd');
Returns:
43 2020-10-18
It looks like week number in a year counted from Sundays and day number in a week is counted from Mondays because Monday is 19th:
select date_format('2020-10-18','w u'), from_unixtime(unix_timestamp('2020, 43, 1', 'yyyy, w, u'), 'yyyy-MM-dd');
returns
43 2020-10-19
If that is true, you can fix it by subtracting 60*60*24 from unix_timestamp:
select date_format('2020-10-18','w'), from_unixtime(unix_timestamp('2020, 43, 1', 'yyyy, w, u')-60*60*24, 'yyyy-MM-dd');
Returns:
43 2020-10-18
UPDATE: Surprisingly, if not providing day in a week, only year and week number, it works also counting Sunday as a week day by default but it will be not correct for other dates for example 2020-01-20, it will return the same Sunday 2020-01-18, check it yourself:
select date_format('2020-10-18','w'), from_unixtime(unix_timestamp('2020, 43', 'yyyy, w'), 'yyyy-MM-dd');
returns:
43 2020-10-18
So, if you do not have day in a week and do not need absolutely accurate date, then use
from_unixtime(unix_timestamp('2020, 43', 'yyyy, w'), 'yyyy-MM-dd');
Or like this (year and week number are selected from the table):
select from_unixtime(unix_timestamp(concat(col_year, ', ', col_week), 'yyyy, w'), 'yyyy-MM-dd') from your_table;

Related

Posgresql standard week of year to israel week of year

I have a query to select data and group by date(data year by years), I need to convert select data from standard week(monday to sunday) to israel week(which start from sunday and end on saturday)
my query:
select
data_date,
CONCAT(to_char(data_date::date, 'IYYY'), 'W', to_char(data_date::date, 'IW')) as standard_week,
CONCAT(to_char(data_date::date, 'IYYY'), 'W', floor(EXTRACT(doy FROM data_date::TIMESTAMP)/7 + 1)) as israel_week
from
data
where
data_date >= '2022-01-01'
and data_date <= '2022-01-31'
group by data_date, standard_week, israel_week
order by data_date
the result like this:
standard week looks ok but israel week was wrong, how can I make it correct?

How to truncate a date to the beginning of week (Sunday)?

I need to truncate dates to the start of week, which is Sunday in my case. How can I do this in PostgreSQL? This truncates to Monday:
date_trunc('week', mydate)
If you subtract the dow value (0 for Sundays, 6 for Saturdays) from the current date than you get the previous Sunday which is the begin of your Sunday-based week
demo:db<>fiddle
SELECT
my_date - date_part('dow', my_date)::int
FROM
my_table
Further reading, documentation
You could truncate the date to the week's Monday, then subtract 1 day, e.g:
SELECT (date_trunc('week', now() + interval '1 day') - interval '1 day')::DATE;
date
------------
2019-06-16
As per documentation, date_trunc() accepts values of type date and timestamp and returns a timestamp (thus the cast at the end).

How to retrieve only Thursday dates by passing any date in a week

I need to get only Thursday dates when I pass any date in that week using built-in date functions in postgres. How?
Do you want to get the date of the same weeks thursday returned? That would be:
SELECT date_trunc('week','2020-02-15'::date) + interval '4 days'
You could use the EXTRACT( dow FROM date) function to get what day of the week a given date is and test if the result is a 4, which should be a thursday.
SELECT
days :: DATE,
to_char(days,'Day'),
EXTRACT(dow FROM days) as day_of_week
FROM generate_series ('2019-02-01', '2019-02-28', '1 day' :: interval ) AS days
https://www.postgresql.org/docs/9.0/functions-datetime.html

Count days for each month between two dates - postgresql

I am trying to write a query which gives the number of days in each month between two specified dates.
Example:
date 1: 2018-01-01
date 2: 2018-05-23
Expected Output:
month days
2018-01-01, 31
2018-02-01, 28
2018-03-01, 31
2018-04-01, 30
2018-05-01, 23
Use generate_series and group by date_trunc
SELECT date_trunc('month',dt) AS month,
COUNT(*) as days
FROM generate_series( DATE '2018-01-01',DATE '2018-05-23',interval '1 DAY' )
as dt group by date_trunc('month',dt)
order by month;
Demo

T-sql Monday before date

I work at a college and our student management systems academic year start date is determined by the Monday on or before the 1st of August. I need to match this in my query, is there a way to easily get the date of the Monday on or before this date.
The accepted answer didn't work for me because I needed both a Sunday week and a Monday week in the same query. This works across different "datefirst" settings:
SELECT DATEADD(d, -((DATEPART(WEEKDAY, '20110515') - DATEPART(dw, '19000101') + 7) % 7), '20110515')
"DATEPART(dw, '19000101')" will determine your "datefirst" setting since 1900-01-01 was on a Monday. If you want a Tuesday based week, you can change 19000101 to 19000102.
BTW, '20110515' is the only date format that works across all SQL Server culture settings. Dates like '2011-05-06' will get mis-interpreted in certain countries. (credit to Itzik Ben-Gan for pointing this out)
set datefirst 1; -- Make Monday the first day of the week
select dateadd(dd, -1*(datepart(dw, '2009-08-01')-1), '2009-08-01')
Returns July 27th, 2009, which is the Monday on or before August 1. Change it to 2005 when Aug 1 was a Monday and the query will return 08-01
You could use datepart to get the weekday, and then do a little math to back into your monday. This example is using the US default of datefirst 7 (in which Monday is day 2 of the week). Adjust the days to add to be which day of the week Monday is for your locale.
select dateadd(dd, -datepart(dw, '2009-08-01') + 2, '2009-08-01')
very hacky
DECLARE #weekday int
SELECT #weekday = DATEPART(WEEKDAY, '1-Aug-2009')
SELECT CASE
WHEN #weekday = 1 THEN '1-Aug-2009' ELSE DATEADD ( dd,(#weekday-2)*-1, '1-Aug-2009')
END
This is a generic algorithm that will return the first Monday of any month (#inputdate):
DATEADD(wk, DATEDIFF(wk, 0, dateadd(dd, 6 - datepart(day, #inputDate), #inputDate)), 0)
It is a common method for getting the first monday of the month in SQL Server. This link explains how the above calculation works along with many other date calculations.
Here is how the above algorithm could be used to get the Monday on or before the 1st day of a month:
-- Set month to get Monday before or at 1st of month.
DECLARE #inputDate DATETIME
SET #inputDate = '2009-08-01'
-- Get first Monday of month.
DECLARE #firstMonday DATETIME
SET #firstMonday = DATEADD(wk, DATEDIFF(wk, 0, dateadd(dd, 6 - datepart(day, #inputDate), #inputDate)), 0)
-- Determine date for first Monday on or before 1st of month.
DECLARE #startDate DATETIME
SET #startDate = #firstMonday
IF #firstMonday > #inputDate
SET #startDate = DATEADD(wk, -1, #firstMonday)
SELECT #startDate