const referenceDate = new Date(2017, 1, 20) //週起算日
const cycle = 364 //週のサイクル
const dateT = ["日","月","火","水","木","金","土"]
/**
* 日付から週を取得
*/
function date2Nweek(date) {
let diff = date.getTime() - referenceDate.getTime()
let diffDays = Math.floor(diff / (1000*60*60*24))
if (diffDays < 0) {
diffDays = (cycle - Math.abs(diffDays) % cycle) % cycle
}else if (diffDays >= cycle) {
diffDays = diffDays % cycle
}
let nWeek = Math.floor(diffDays / 7) + 1
let DayOfTheWeek = dateT[date.getDay()]
return [nWeek, diffDays]
}
/**
* 指定日の週を取得
* @param date 対象の日付:dateObject
* @param nWeek 週数:number
* @param diffDays 基準日からの差日数:string
*/
function nWeek2Period(date, nWeek, diffDays) {
let targetWeek = new Date(date)
targetWeek.setDate(date.getDate() + ((nWeek-1)*7 - diffDays))
let endTargetWeek = new Date(targetWeek)
endTargetWeek.setDate(endTargetWeek.getDate() + 6)
return [targetWeek, endTargetWeek]
}
/**
* 逆引き
* @param nWeek 対象の週:number
* @param flg +-年度:number
*/
function calcSchedule(nWeek, flg = 0) {
let date = new Date()
//現在の週を取得
let retNweek = date2Nweek(date)
//表示年度の基準日を取得
date.setDate(date.getDate() + (flg*cycle - retNweek[1]))
//表示する週の日付を取得
date.setDate(date.getDate() + 7*(nWeek-1))
//表示する日付の週を取得
retNweek = date2Nweek(date)
let retPeriod = nWeek2Period(date, retNweek[0], retNweek[1])
let retMessage = `表示週第${retNweek[0]}週は\n`
+ `${retPeriod[0].getFullYear()}年${retPeriod[0].getMonth()+1}月${retPeriod[0].getDate()}日(${dateT[retPeriod[0].getDay()]})`
+ `~${retPeriod[1].getFullYear()}年${retPeriod[1].getMonth()+1}月${retPeriod[1].getDate()}日(${dateT[retPeriod[1].getDay()]})です。`
return retMessage
}
/**
* 表示週
* @param date 対象の日付:dateObject
*/
function schedule(date = new Date()) {
let retNweek = date2Nweek(date)
let retPeriod = nWeek2Period(date, retNweek[0], retNweek[1])
let retMessage = `${date.getFullYear()}年${date.getMonth()+1}月${date.getDate()}日(${dateT[date.getDay()]})の週は第${retNweek[0]}週です。\n`
+ `第${retNweek[0]}週は`
+ `${retPeriod[0].getFullYear()}年${retPeriod[0].getMonth()+1}月${retPeriod[0].getDate()}日(${dateT[retPeriod[0].getDay()]})`
+ `~${retPeriod[1].getFullYear()}年${retPeriod[1].getMonth()+1}月${retPeriod[1].getDate()}日(${dateT[retPeriod[1].getDay()]})です。`
return retMessage
}
/**
* Example
*
*/
//表示週テスト
// let d = new Date(2019,1,18)
console.log(schedule(new Date(2019,1,17)))
//逆引き表示週テスト
// console.log(calcSchedule(51, 0))
このような感じになっているのですが、これだと53週目が表示されないため、
1週目にしたいところがずれていきます。
たとえば表示週テストにて「console.log(schedule(new Date(2022,1,21)))」にすると、
"2022年2月21日(月)の週は第2週です。第2週は2022年2月21日(月)~2022年2月27日(日)です。"
となってしまいます。うるう年が来るたびに1週ずつずれてしまうのでどうにかしたいです。
一応1週目であるべきものを記載しておきます。とても困ってます。宜しくお願いします。
1週目にしたい日付
2018/2/19
2019/2/18
2020/2/17
2021/2/15 ---ここまでは問題なし
2022/2/21 ---ここから2週目になってしまう
2023/2/20
2024/2/19
2025/2/17
2026/2/16
2027/2/15
2028/2/21 ---ここから3週目になってしまう
・
・
・