In order to create a weekly calendar that shows me the days of a given week, I am looking for a solution that will do this. The output should show me the days from given data, starting from Monday to Sunday. To achieve this I'm using dayjs
in nuxt. I wrote a method and thought I was done so far. However, this is not the case after I have tested out different years.
As seen here ISO week date, I thought I would be well served with .isoWeek()
.
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, although ISO 8601 does not use this term.
const year = 2022
const calendarWeek = 1 //1 to 53
const dayjs = this.$dayjs
const isoWeek = require('dayjs/plugin/isoWeek')
dayjs.extend(isoWeek)
const week = dayjs().year(year).isoWeek(calendarWeek)
const startOfWeek = dayjs(week).day(1)
const weekdays = new Array(7).fill(startOfWeek).map(
(day, idx) => day.add(idx, 'day').format('dddd, DD MMM YYYY'))
This will output me the expected result with the dates between Monday, 03 Jan 2022
and Sunday, 09 Jan 2022
. Great, that's exactly how it should be.
The discovered problem: If I insert the first calendar week of 2023, I get the following output:
const year = 2023
const calendarWeek = 1
Output: Dates between Monday, 09 Jan 2023
and Sunday, 15 Jan 2023
It should be 02. Jan
- 08. Jan
. This is the result I would get if I specified 0
as calendarWeek
. Why does 1
work for 2022 and not for 2023? Thus the correct functionality of my calendar is no longer possible.
In short, you want to get the first week which includes the first monday of the year...
But what you actually get is the second week of the year (isoWeek
is zero-based).
The first week of the year is the one that contains at least one date of that year (January 1st).
For 2022, that monday is December 27th, 2021.
In this case, just compare the year and add 7 days if necessary.
I have made it a function with just the year
and week
as argument:
function getWeekOfYear(year, week) {
// The first monday of the first week includes at least one day of the year
let firstMondayOfYear = dayjs().year(year).isoWeek(week).day(1);
console.log("Monday 1:", firstMondayOfYear.format("dddd, DD MMM YYYY"));
// Now make sure it really is the first monday of the year
if (firstMondayOfYear.year() !== year) {
firstMondayOfYear = firstMondayOfYear.add(7, "days");
}
console.log("Monday 2:", firstMondayOfYear.format("dddd, DD MMM YYYY"));
// return the week for that "real" first monday of the year
return new Array(7)
.fill(firstMondayOfYear)
.map((day, idx) => day.add(idx, "day").format("dddd, DD MMM YYYY"));
}
console.log("result for 2022 - week 0", getWeekOfYear(2022, 0))
console.log("result for 2023 - week 0", getWeekOfYear(2023, 0))
console.log("result for 2022 - week 52", getWeekOfYear(2022, 52))
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.6/dayjs.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.6/plugin/isoWeek.min.js"></script>
<script>
dayjs.extend(window.dayjs_plugin_isoWeek)
</script>