Allart
Allart

Reputation: 928

How to calculate the amount of weeks between two week pickers

I created two week pickers (html input type="week"). I want to know how much weeks are in between the two weeks selected. These are my two html week pickers:

<input type="week" id="weekPicker1" required="required" min="1971-W01" max="2071-W52" value="2021-W01">
<input type="week" id="weekPicker2" required="required" min="1971-W01" max="2071-W52" value="2021-W52">

It returns 2021-W01 and 2021-W52 as a string.

In this case there are 52 weeks between the dates. But how can I make Javascript know this as well?

I have this Javascript code to make sure I get the years and weeks as numbers:

// Get dates in usable format.
let startDate = inputFields[0].value.split("-");
let startYear = Number(startDate[0]); //2021
let startWeek = Number(startDate[1].replace("W", "")); //1

let endDate = inputFields[1].value.split("-");
let endYear = Number(endDate[0]); //2021
let endWeek = Number(endDate[1].replace("W", "")); //52

But now, how do I calculate this?

I thought of this:

var yearDiff = endYear - startYear;
var amountOfWeeks = endWeek - startWeek;

amountOfWeeks += yearDiff * 52;

I think it nearly works, except not every year has 52 weeks (leap year). So how should I do this efficiently?

Edit:

I would like to see it in pure JS. No library or things like that. And I want the amount of weeks based on a calendar like this. So calculation based on a 7 day week will not give what I want.

In the end I need to use the weeks to do calculations. So using a date picker to select weeks still seems wrong. I also tested if I could do the calculation based on days etc, but it will give wrong results. Calculation I have to do: (selected length of weeks) : (max amount of weeks in year) * 200.

Upvotes: 0

Views: 900

Answers (2)

reharis
reharis

Reputation: 412

there are 52 weeks + 1 day in a year and 52 weeks + 2 days in a leap year. So your suggestion amountOfWeeks += yearDiff * 52; does not seem accurate. The below function converts the start and end year and weeks into miliseconds, subract and convert back into weeks. It should work with leap years. I haven't tested it though.

function compareWeeks(startYear, startWeek, endYear, endWeek) {
    
    const start =
        new Date(startYear, 0).getTime() + startWeek * 7 * 24 * 60 * 60 * 1000

    const end = 
        new Date(endYear, 0).getTime() + endWeek * 7 * 24 * 60 * 60 * 1000

    const diff = Math.abs(end - start)
    const diffWeeks = diff / 1000 / 60 / 60 / 24 / 7
    return diffWeeks
}

Update for ISO-week-numbering year (your use case):
According to the wikipedia, an ISO Year has either 52 or 53(ISO Leap Year) weeks. 53 when it starts or ends with Thirsday else 52. Checkout the below code:

function weeksInBetween(startYear, startWeek, endYear, endWeek) {
    let diff = 0
    for (let i = startYear; i < endYear; i++) {
        const has53Weeks = isISOLeapYear(i)
        if (has53Weeks) {
            diff += 53
        } else {
            diff += 52
        }
    }

    return (diff += endWeek - --startWeek)
    /* 
        the '--startWeek' makes sure the starting week
        is not subtracted from the result, because you
        want the result to be inclusive'
        
    */
}

function isISOLeapYear(year) {
    const startsWithThursday =
        new Date(year, 0, 1).toString().split(' ')[0] === 'Thu'
    const endsWithThursday =
        new Date(year, 11, 31).toString().split(' ')[0] === 'Thu'

    if (startsWithThursday || endsWithThursday) {
        return true
    }

    return false
}

console.log(
    weeksInBetween(2020, 1, 2021, 52), // 105
    weeksInBetween(2009, 1, 2010, 52), // 105
    weeksInBetween(2021, 1, 2021, 52), // 52
    weeksInBetween(2021, 1, 2022, 52), // 104
    weeksInBetween(2021, 1, 2021, 1)   // 1
)

Upvotes: 1

morganney
morganney

Reputation: 13580

Use date-fns and differenceInCalendarWeeks.

const result = differenceInCalendarWeeks(
  startDate,
  endDate
)

Upvotes: 1

Related Questions