settingsログイン
メニュー

【急ぎ】指定日が第何週目かを返したい【週計算】

閲覧 62
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週目になってしまう
  ・
  ・
  ・
ウェブデザイナー見習い 2018 3/30 質問 JavaScript

ログインまたはユーザー登録してから回答してください。

プログラミング・開発言語、JavaScript の企業/事業者/教室/プロの方のホームページの集客、アクセスアップ、SEO対策効果が期待できるリスティングサイト=Ask-itをぜひご活用ください

Ask IT にようこそ。ここではコミュニティメンバーに質問したり、回答を得ることができます。
ITについて質問したい方へ ITについてプロに質問したい方は会員登録後すぐに質問をする事ができます。

プロフェッショナルの方へ 質問に答えていただけるプロフェッショナルの方は下記をご覧下さい

お気づきの点があれば是非お知らせください
...