Repository: JuliaLang/julia
File: stdlib/Dates/src/accessors.jl (Julia)

Code before:
    return m > 12 ? m - 12 : m
end
function monthday(days)
    z = days + 306; h = 100z - 25; a = fld(h,3652425); b = a - fld(a,4)
    y = fld(100b + h, 36525); c = b + z - 365y - fld(y, 4); m = div(5c + 456, 153)
    d = c - div(153m - 457, 5); return m > 12 ? (m - 12, d) : (m, d)
end
function day(days)
    z = days + 306; h = 100z - 25; a = fld(h,3652425); b = a - fld(a,4)
    y = fld(100b + h, 36525); c = b + z - 365y - fld(y, 4); m = div(5c + 456, 153)
    return c - div(153m - 457, 5)
end

# ISO year utils
# https://en.wikipedia.org/wiki/Talk:ISO_week_date#Algorithms
const WEEK_INDEX = (15, 23, 3, 11)
function week(days)
    w = div(abs(days - 1), 7) % 20871
    c, w = divrem((w + (w >= 10435)), 5218)
    w = (w * 28 + WEEK_INDEX[c + 1]) % 1461
    return div(w, 28) + 1
end

"""
Year defined as ISO year. The equivalent is
`week(lastdayofyear(dt) - Day(3))`  as 28 december is always in the last week
"""
function weeksinyear(dt::DateTime)
    firstday = firstdayofyear(dt)
    lastday = lastdayofyear(dt)

    if dayofweek(firstday) == 4 || dayofweek(lastday) == 4
        return 53
    end
    return 52
end

"""
Return current ISO year as defined in
https://en.wikipedia.org/wiki/ISO_week_date
"""
function isoyear(dt::DateTime)
    thisyear = Year(dt)
    thismonth = Month(dt)
    weeknumber = week(dt)
    if weeknumber >= 52 && thismonth.value == 1
        # If it is january, then its the iso year from before
        return Year(thisyear.value - 1)
    elseif weeknumber == 1 && thismonth.value == 12
        # If it is december, then its the next year
        return Year(thisyear.value + 1)

Review comment (suggestion):
This should probably go as a comment inside of the function. The docstring should be user-oriented, for example:

```suggestion
Return the number of ISO weeks in the given year (see https://en.wikipedia.org/wiki/ISO_week_date).
```


Code after:
    return m > 12 ? m - 12 : m
end
function monthday(days)
    z = days + 306; h = 100z - 25; a = fld(h,3652425); b = a - fld(a,4)
    y = fld(100b + h, 36525); c = b + z - 365y - fld(y, 4); m = div(5c + 456, 153)
    d = c - div(153m - 457, 5); return m > 12 ? (m - 12, d) : (m, d)
end
function day(days)
    z = days + 306; h = 100z - 25; a = fld(h,3652425); b = a - fld(a,4)
    y = fld(100b + h, 36525); c = b + z - 365y - fld(y, 4); m = div(5c + 456, 153)
    return c - div(153m - 457, 5)
end

# ISO year utils
# https://en.wikipedia.org/wiki/Talk:ISO_week_date#Algorithms
const WEEK_INDEX = (15, 23, 3, 11)
function week(days)
    w = div(abs(days - 1), 7) % 20871
    c, w = divrem((w + (w >= 10435)), 5218)
    w = (w * 28 + WEEK_INDEX[c + 1]) % 1461
    return div(w, 28) + 1
end

"""
Return the number of ISO weeks in the given year (see https://en.wikipedia.org/wiki/ISO_week_date).

# Examples
```jldoctest
julia> weeksinyear(Year(2022))
52

julia> weeksinyear(Year(2020))
53
```
!!! compat "Julia 1.13"
    This function requires Julia 1.13 or later.
"""
function weeksinyear(y::Year)
    firstday = firstdayofyear(Date(y))
    lastday = lastdayofyear(Date(y))

    if dayofweek(firstday) == 4 || dayofweek(lastday) == 4
        return 53
    end
    return 52
end

"""
Return the ISO year that contains `dt` (see https://en.wikipedia.org/wiki/ISO_week_date).

# Examples