按星期,星期和年份设置日期

时间:2020-01-09 14:23:50

标签: javascript date

我正在建立日历。我的日历上有一些活动会在每周的同一天每年重复一次。

例如:

  • eventOne,星期三(0),第3周

  • eventTwo,星期二(2),第12周

EventOne应该有一个日期对象,该对象始终是当年第三周的星期日。

EventTwo的日期对象应始终为当年第12周的星期二。

function getDateOfISOWeek(w, y) {
  var simple = new Date(y, 0, 1 + (w - 1) * 7)
  var dow = simple.getDay()
  var ISOweekStart = simple
  if (dow <= 4)
    ISOweekStart.setDate(simple.getDate() - simple.getDay() + 1)
  else
    ISOweekStart.setDate(simple.getDate() + 8 - simple.getDay())
  return ISOweekStart
}

const date = getDateOfISOWeek(3, 2020)
console.log(date)

上面的函数将为我提供请求的一周的第一天,但​​在一周中的一天没有实现,因此我一直在努力寻找Date函数来完成此任务。

如果有任何方便的功能可以帮助我,我很乐意使用moment或date-fns,但是如果我可以使用本机javascript解决方案,则更愿意。

3 个答案:

答案 0 :(得分:1)

我不确定,但是如果我理解正确,您可以使用date-fns来做到这一点:

var startOfYear = require('date-fns/start_of_year')
var getDay = require('date-fns/get_day')
var addDays = require('date-fns/add_days')
var addWeeks = require('date-fns/add_weeks')    

let getDateOfISOWeek = (w, y, d) => {
  let startDayOfYear = startOfYear(new Date(y,0,1));
  let diff = d - getDay(startDayOfYear);
  let firstAppearanceOfYear = addDays(startDayOfYear, diff < 0 ? 7 + diff : diff);
  return addWeeks(firstAppearanceOfYear, w - 1);
}

let result = getDateOfISOWeek(3, 2020, 0); //Sun Jan 19 2020
let result2 = getDateOfISOWeek(3, 2021, 0); // Sun Jan 17 2021

前两个参数-周和年,第三个参数-您要查找的天的索引(0-星期日,6-星期六)

答案 1 :(得分:1)

getDateOfISOWeek 可以正常工作,尽管有点笨重。您只需要添加所需的天数即可获得所需的特定日期。

ISO周从星期一开始,因此只需要确定一周的开始并将天数减去1就可以了。星期日可以是0或7,因此ECMAScript或ISO编号都可以。

/* Return date for start of ISO week in given year
** @param {number|string} week: required ISO week number
** @param {number|string} year: required year
** @returns {Date} date of Monday at start of week
*/
function getDateOfISOWeek(week, year) {
  // Get date for 1 Jan in given year
  let d = new Date(year, 0, 1);
  let dow = d.getDay();

  // Shift to start of ISO week 1
  d.setDate((dow <= 4? 2 : 9) - d.getDay());
  
  // Add required number of weeks
  d.setDate(d.getDate() + (week - 1)*7);
  
  return d;
}

/* Return date for a day in given ISO week in given year
** @param {number|string} day: day number, Mon=1, Tue=2, ... Sun=0 or 7
** @param {number|string} week: required ISO week number
** @param {number|string} year: required year
** @returns {Date} date of required day
*/
function getDayOfISOWeek(day, week, year) {
  let d = getDateOfISOWeek(week, year);
  d.setDate(d.getDate() + (+day || 7) - 1);
  return d;
}

// Options for formatting dates
let opts =  {weekday:'short', day:'numeric', month:'short', year:'numeric'};

// Examples
[[1, 3,2020], // Mon, week 3, 2020
 [0, 1,2020], // Sun, week 1, 2020
 [7, 1,2020], // Sun, week 1, 2020
 [5,10,2020], // Fri, week 10, 2020
 [6,27,2022], // Sat, week 27, 2022
 [2,12,2020], // Tue, week 12, 2020
 [2,12,2021], // Tue, week 12, 2021
 [2,12,2022]  // Tue, week 12, 2022
].forEach(args => console.log(
  args + ': ' + getDayOfISOWeek(...args).toLocaleString(void 0, opts)
));

PS。您确实应该为括号和分号添加大括号以终止语句,否则您将很难找到一些错误。

答案 2 :(得分:0)

您可以简单地实现这样的功能,只需将周数乘以7即可得到偏移量。并基于1月4日计算偏移量(因为该天是always in the 1st week

注意:

  • 如果您将星期日视为一周的第一天,则将0传递为weekDay,而如果您将星期日视为一周的最后一天,则应传递7。
  • week是基于一个的,传递1可能会导致日期具有上一年的值(例如createDate(2020, 1, 1)将返回2019年12月30日。

function createDate(year, week, weekDay){
  const date = new Date(year, 0, 4)
  const offset = (date.getDay() || 7) - weekDay
  date.setDate(week * 7 - offset - 3)
  return date
}

console.log(createDate(2020,3,7).toDateString())
console.log(createDate(2021,3,7).toDateString())
console.log(createDate(2020,12,4).toDateString())
console.log(createDate(2021,12,4).toDateString())
console.log(createDate(2015,1,4).toDateString())