Dates.jl - week last week of year/first week of year

Hi everyone, I have daily level data spanning multiple years, and I want to aggregate it to the weekly level.

week(DateTime(2020, 12, 31))

week(DateTime(2021, 01, 01))

I noticed that the week function considers both these dates as the 53rd week of 2020.

Is there either:

  1. There is a way for the Dates.jl package to tell me that January 1 2021 is the 53rd week of 2020 specifically, rather than just the 53rd week of a year?

  2. Preferably, is there an alternative week function, where the week counter resets at the start of each year, so January 1 2021 is the first week of 2021?

Thanks!

I had to check the default myself, but I think the packages mainly follows the ISO default: ISO week date - Wikipedia

So is there a specific reason you want to deviate from that standard?

TLDR: I don’t have to depart from that standard, but it’d be nice to know the accompanying year of a given week, so I can easily know that January 1 2021 is the 53rd week of 2020, not 2021.

Long version: I have a Date column in my dataset, which is across multiple years. I wanted to do some aggregating calculations at the weekly level, so I was going to extract the week and year from the Date column. However, this wouldn’t work for January 1 2021 - it’d be recorded as the 53rd week of 2021.

But if you move that week, Dec 31 I suddenly in the next year? You have to hit a year where Sunday is the 31st and Monday is the 1st, for not having this problem. In all other years either of those days is “in the wrong year” (or in the right one at least according to the ISO definition).

One thing you could do, is introducing a week 0 – but also then be careful to then not accidentally counting the week twice (in both years).

Would that work for you?

julia> function dateinfo(d::Date)
           tmp = d - Day(dayofweek(d)-1)
           week(tmp), year(tmp)
       end
dateinfo (generic function with 1 method)

julia> Date(2020, 12, 31) |> dateinfo
(53, 2020)

julia> Date(2021, 01, 01) |> dateinfo
(53, 2020)
1 Like

Perhaps this might work:

using Dates

function nonisoweek(d)
    Jan01 = Date(year(d), 1, 1)
    FirstSunday = Date(year(d), 1, 1 + (7 - dayofweek(Jan01)))
    Dec31 = Date(year(d), 12, 31)
    LastSunday = Date(year(d), 12, 31 - dayofweek(Dec31) )
    if d <= FirstSunday
        return (1, year(d))
    elseif d > LastSunday
        return (1, year(d) + 1)
    else
        return ((d - FirstSunday).value Ă· 7 + 2, year(d))
    end
end

nonisoweek(Date(2020,12,31))        # (1, 2021)
nonisoweek(Date(2021, 1, 1))        # (1, 2021)
nonisoweek(Date(2024,12,29))        # (53, 2024)
nonisoweek(Date(2024,12,30))        # (1, 2025)