Week numbering sounds simple, but as most calendar-related topics it is not,
e.g. see wikipedia on the ISO week date.
Week numbering is very important to our customers.
I know I can defer to the native functionality of my databases.
But does Dremio comply with ISO 8601 for week numbering?
Currently, I work around this by pushing all date values to the client. My main client app is Superset atm. In Superset, you can use d3-time-format | D3 by Observable to format week numbers in an ISO8601 compatible way.
In Superset, to format weeknumbers, use %g for matching year, %V for week number and %u for day number matching iso 8601 week calendar: 24.17-1: %g.%V-%u
Dremio calculates WEEK OF YEAR using ISO 8601 standards which follows these rules:
Weeks start with Monday and end on Sunday. Each week’s year is the Gregorian year in which the Thursday falls. The first week of the year, hence, always contains 4 January. ISO week year numbering therefore usually deviates by 1 from the Gregorian for some days close to 1 January.
Dremio doesn’t seem to expose a YEAR OF WEEK function to return the week’s year according to ISO 8601 standard.
Most businesses in the US like their week numbers to follow these rules:
January 1st of any year always starts with Week 1
First day of week is Monday and not Sunday
You can achieve this with a Dremio User Defined Function like this:
CREATE OR replace FUNCTION udf.week_of_year_us(input date)
returns int
RETURN
(
SELECT 1 + (Dayofyear(input) +
CASE
WHEN Dayofweek(Date_trunc('YEAR',input)) = '1' THEN 5
WHEN Dayofweek(Date_trunc('YEAR',input)) = '2' THEN 0
WHEN Dayofweek(Date_trunc('YEAR',input)) = '3' THEN 0
WHEN Dayofweek(Date_trunc('YEAR',input)) = '4' THEN 1
WHEN Dayofweek(Date_trunc('YEAR',input)) = '5' THEN 2
WHEN Dayofweek(Date_trunc('YEAR',input)) = '6' THEN 3
WHEN Dayofweek(Date_trunc('YEAR',input)) = '7' THEN 4
END ) / 7 AS woy_us);
Usage Examples:
select WEEKOFYEAR(cast('2022-12-31' as date)), udf.week_of_year_us(cast('2022-12-31' as date)); // Returns 52, 53
select WEEKOFYEAR(cast('2023-01-01' as date)), udf.week_of_year_us(cast('2023-01-01' as date)); // Return 52, 1
select WEEKOFYEAR(cast('2023-01-02' as date)), udf.week_of_year_us(cast('2023-01-02' as date)); // Returns 1 , 2 (2023-01-02 is a Monday)