Reputation: 928
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
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
Reputation: 13580
Use date-fns
and differenceInCalendarWeeks
.
const result = differenceInCalendarWeeks(
startDate,
endDate
)
Upvotes: 1