# Determine date range given year and week number

**URL:** <https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878>\
**Category:** General Usage\
**Tags:** question, dates, standard-lib\
**Created:** [February 1, 2023, 4:49pm UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878 "2023-02-01T16:49:40Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![isentropic](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/isentropic/32/11894_2.png) [@isentropic](https://discourse.julialang.org/u/isentropic)\
**Post date:** [February 1, 2023, 4:49pm UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/1 "2023-02-01T16:49:40Z")

</div>

How can I get the date range (or just the `Date` of the Monday) of that week?  
For example, I have year = 2023 week=5, somehow I need to know that the Monday of that week is 2023-01-30.  
Using a relevant contructor from [Dates · The Julia Language](https://docs.julialang.org/en/v1/stdlib/Dates/#Constructors) does not help, it just does not work sadly:

```julia
julia> Date(Dates.Week(5), Dates.Year(2023),)
2023-01-01

```

Issue in julia posted [`Date(Dates.Week(5), Dates.Year(2023))` (week, year) constructor is not working · Issue #48490 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/48490)

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [February 1, 2023, 5:07pm UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/2 "2023-02-01T17:07:50Z")

</div>

Is this what you need?

```julia
julia> using Dates

julia> year = 2023
2023

julia> week = 5
5

julia> monday = firstdayofweek(Date(Year(year)) + Week(week))
2023-01-30

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [February 1, 2023, 7:04pm UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/4 "2023-02-01T19:04:57Z")

</div>

And for the range from Monday to Friday:

```julia
using Dates
y = 2023
w = 5
monday = firstdayofweek(Week(w) + Date(Year(y)))
r = monday:(monday+Day(4)) # range Mon to Fri

```

---

<div class="post-metadata">

**Author:** ![isentropic](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/isentropic/32/11894_2.png) [@isentropic](https://discourse.julialang.org/u/isentropic)\
**Post date:** [February 2, 2023, 2:19am UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/5 "2023-02-02T02:19:07Z")

</div>

Thanks all, I’m not so sure about the correctness of these solutions. Because for some reason definition of the first week of the year is a little strange. Excerpt from [wiki](https://en.wikipedia.org/wiki/ISO_week_date)

> An **ISO week-numbering year** (also called _ISO year_ informally) has 52 or 53 full weeks. That is 364 or 371 days instead of the usual 365 or 366 days. These 53 week years occur on all years that have Thursday as the 1st of January and on leap years that start on Wednesday the 1st. The extra week is sometimes referred to as a _[leap week](https://en.wikipedia.org/wiki/Leap_week)_, although ISO 8601 does not use this term.

I’m almost sure that Julia adheres to this. I’m afraid the solutions you posted might not be always correct. I know better than implementing my own datetime logic, as there could be so many edge cases.

---

<div class="post-metadata">

**Author:** ![isentropic](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/isentropic/32/11894_2.png) [@isentropic](https://discourse.julialang.org/u/isentropic)\
**Post date:** [February 2, 2023, 2:20am UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/6 "2023-02-02T02:20:42Z")

</div>

Your solution looks nice, but somehow I need to account for this weird definition of week number. And if we account for this maybe it worth including this in julia std lib

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [February 2, 2023, 4:06am UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/7 "2023-02-02T04:06:43Z")

</div>

Is it helpful? (if so, it deserves some testing)

```julia
function firstmondayofISOyear(year)
  date = Date(Year(year))
  firstthursdayofyear = firstdayofweek(date) + Day(3)
  yr = Year(firstthursdayofyear).value
  if yr < year
    firstthursdayofyear += Day(7)
  end
  firstthursdayofyear - Day(3)
end

```

also

```julia
help?> Dates.week
  week(dt::TimeType) -> Int64

  Return the ISO week date
  (https://en.wikipedia.org/wiki/ISO_week_date) of a Date or DateTime
  as an Int64. Note that the first week of a year is the week that
  contains the first Thursday of the year, which can result in dates
  prior to January 4th being in the last week of the previous year. For
  example, week(Date(2005, 1, 1)) is the 53rd week of 2004.

  Examples
  ≡≡≡≡≡≡≡≡

  julia> week(Date(1989, 6, 22))
  25

  julia> week(Date(2005, 1, 1))
  53

  julia> week(Date(2004, 12, 31))
  53

```

---

<div class="post-metadata">

**Author:** ![isentropic](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/isentropic/32/11894_2.png) [@isentropic](https://discourse.julialang.org/u/isentropic)\
**Post date:** [February 2, 2023, 4:50am UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/8 "2023-02-02T04:50:07Z")

</div>

This looks great, thank you. Perhaps this could be tested and extended such that,  
`Date(Dates.Week(5), Dates.Year(2023),)` would work in std lib of julia. I’ll try to get to do that if you allow me to use your code

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [February 2, 2023, 9:40am UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/9 "2023-02-02T09:40:38Z")

</div>

Yes I think the following functions should be defined for any `TimeType`:

- `isoyear` (like `week` but giving the year)
- `firstdayofisoyear` (like `firstdayofyear` but for the ISO year)
- `lastdayofisoyear`
- `weeksinyear` (similar to `daysinmonth`)

And extend the `Date` and `DateTime` constructors to accept a `Week` period too. It should then be documented that a `Week` or `Month` can be in the parameters, but not both. And if a `Week` is given, then `Year` is interpreted as ISO year and `Day` as day in the week.

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [February 2, 2023, 11:05am UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/10 "2023-02-02T11:05:13Z")

</div>

You have my permission to do whatever you like with this.

---

<div class="post-metadata">

**Author:** ![hhaensel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hhaensel/32/1207_2.png) [@hhaensel](https://discourse.julialang.org/u/hhaensel)\
**Post date:** [March 27, 2025, 11:29am UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/11 "2025-03-27T11:29:06Z")

</div>

> [@JeffreySarnoff](#):
>
> ```julia
> function firstmondayofISOyear(year)
> date = Date(Year(year))
> firstthursdayofyear = firstdayofweek(date) + Day(3)
> yr = Year(firstthursdayofyear).value
> if yr < year
> firstthursdayofyear += Day(7)
> end
> firstthursdayofyear - Day(3)
> end
> 
> ```

If I should propose a solution for Dates.jl, I’d go for a typestable definition

```julia
function firstdayofISOyear(x)
  firstday = firstdayofweek(firstdayofyear(x))
  week(firstday) == 1 ? firstday : firstday + Day(7)
end

firstdayofISOyear(x::Integer) = firstdayofISOyear(Date(Year(x)))
firstdayofISOweek(year, week::Integer) = firstdayofISOyear(year) + Day(7(week - 1))

```

```julia-repl
julia> firstdayofISOyear(2025)
2024-12-30

julia> firstdayofISOyear(today())
2025-03-31

julia> firstdayofISOyear(now())
2025-03-31T00:00:00

julia> firstdayofISOyear(2005)
2005-01-03

julia> firstdayofISOweek(2005, 43)
2005-10-24

julia> firstdayofISOweek(now(), 43)
2025-10-20T00:00:00

```

Any opinions to this version?

---

<div class="post-metadata">

**Author:** ![hhaensel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hhaensel/32/1207_2.png) [@hhaensel](https://discourse.julialang.org/u/hhaensel)\
**Post date:** [March 27, 2025, 1:02pm UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/12 "2025-03-27T13:02:08Z")

</div>

> [@hhaensel](#):
>
> ```julia
> function firstdayofISOyear(x)
> firstday = firstdayofweek(firstdayofyear(x))
> week(firstday) == 1 ? firstday : firstday + Day(7)
> end
> 
> firstdayofISOyear(x::Integer) = firstdayofISOyear(Date(Year(x)))
> firstdayofISOweek(year, week::Integer) = firstdayofISOyear(year) + Day(7(week - 1))
> 
> ```

Just created an issue in Julia [Feature request: add function to calculate the starting date of a week for a given year · Issue #57908 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/57908)

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [March 27, 2025, 6:59pm UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/13 "2025-03-27T18:59:43Z")

</div>

I am reviewing it. Thanks for asking.

Best,  
Jeffrey

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [March 27, 2025, 10:36pm UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/14 "2025-03-27T22:36:50Z")

</div>

```julia
using Dates

function firstdayofISOyear(withyear::T) where {T<:Union{Date, DateTime, Year}}
# date within the first week of ISO year
firstweek = Date(Year(withyear), Month(1), Day(4))
# date of first Monday in ISO year <= [date]from_newyear
firstweek + Day(1 - dayofweek(firstweek))
end

firstdayofISOyear(year::Integer) = firstdayofISOyear(Year(year)

```

---

<div class="post-metadata">

**Author:** ![isentropic](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/isentropic/32/11894_2.png) [@isentropic](https://discourse.julialang.org/u/isentropic)\
**Post date:** [March 28, 2025, 12:51am UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/15 "2025-03-28T00:51:01Z")

</div>

@JeffreySarnoff while at could you please also take a look at the long standing [add ISO year / ISO week utilities by isentropic · Pull Request #48507 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/48507)

I think it is quite related and partially resolves this. It originates from your initial help with this issue back in the day

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [March 30, 2025, 10:25pm UTC](https://discourse.julialang.org/t/determine-date-range-given-year-and-week-number/93878/16 "2025-03-30T22:25:50Z")

</div>

Here are some functions – they need tests (if someone else would write them – [Calendar Converter](https://www.fourmilab.ch/documents/calendar/)  
is reliable (some others are not)).

```julia
function ISOfirstdayofyear(withyear::T) where {T<:Union{Date, DateTime, Year}}
   infirstweek = Date(Year(withyear), Month(1), Day(4))
   # date of first Monday in ISO year <= [date]infirstweek
   infirstweek + Day(1 - dayofweek(infirstweek))
end

ISOfirstdayofyear(year::Integer) = firstdayofISOyear(Year(year))

function ISOlastdayofyear(withyear::T) where {T<:Union{Date, DateTime, Year}}
   year = Year(withyear) + Year(1)
   firstday = ISOfirstdayofyear(year)
   firstday - Day(1)
end

ISOlastdayofyear(year::Integer) = ISOlastdayofyear(Year(year))

function ISOdaysinyear(withyear::T) where {T<:Union{Date, DateTime, Year}}
    ISOlastdayofyear(withyear) - ISOfirstdayofyear(withyear) + Day(1)
end

ISOdaysinyear(year::Integer) = daysinISOyear(Year(year))

function ISOdayofyear(date::T) where {T<:Union{Date, DateTime}}
    datetime2rata(date) - datetime2rata(ISOfirstdayofyear(Year(date)))
end

ISOweekofyear(x) = fld(ISOdayofyear(x), 7) + 1

function ISOyear(date::T) where {T<:Union{Date, DateTime}}
    year = Year(date).value
    first = ISOfirstdayofyear(date)
    last = ISOlastdayofyear(date)
    if date < first
       year - 1
    elseif date > last
       year + 1
    else
       year
    end
end

ISOdayofweek(x) = dayofweek(x)

function ISOyearday(date::T) where {T<:Union{Date, DateTime}}
    (ISOyear(date), ISOdayofyear(date))
end

function ISOyearweekday(date::T) where {T<:Union{Date, DateTime}}
    (ISOyear(date), ISOweekofyear(date), ISOdayofweek(date))
end

function ISOdatetogregorian(isoyear, isoweek, isodayofweek)
     isoday = (isoweek - 1) * 7 + isodayofweek
     infirstweek = Date(Year(isoyear), Month(1), Day(4))
     first = ISOfirstdayofyear(infirstweek)
     first + Day(isoday - 1)
end

```
