首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用JavaScript获取当前一周,而不需要额外的库?[所以例子是错误的]

使用JavaScript获取当前一周,而不需要额外的库?[所以例子是错误的]
EN

Stack Overflow用户
提问于 2018-10-20 17:55:39
回答 1查看 406关注 0票数 -1

我构建了一个日历控件,并添加了周数字作为最后一步,但在SO和SO之外,我能找到的每个脚本示例都遇到了问题(其中大多数都是从另一个脚本中复制过来的)。

问题是,当日期落在部分月份时,周计算似乎变得混乱,当它是新月中的同一周时,要么继续计数,要么认为上个月的最后一个完整周与下个月的第一个完整新周相同。

以下是其中一个库的可视化演示(它们都有自己的不准确性,因为它们通常基于固定的数字来计算周,并从那里构建):

您可以查看codepen here,因为项目相当复杂,我在开始时使用Date.prototype.getWeek函数可以更容易地处理这一点。请随意交换此处提供的示例中的任何代码,因为它们最终都会在几个月内崩溃。

使用的一些计算:

当运行"Get week of year in JavaScript like in PHP“中的最新示例(2017)时,现在返回的周是42。当你查看我的日历时,根据这里的https://www.epochconverter.com/weeks/2018,10月份的那一周显示为42,这是正确的。

给出这个例子,有整整几周共享相同的周数-所以我看不出42是如何准确的。

代码语言:javascript
复制
Date.prototype.getWeek = function (dowOffset) {
/*getWeek() was developed by Nick Baicoianu at MeanFreePath: http://www.epoch-calendar.com */

    dowOffset = typeof(dowOffset) == 'int' ? dowOffset : 0; //default dowOffset to zero
    var newYear = new Date(this.getFullYear(),0,1);
    var day = newYear.getDay() - dowOffset; //the day of week the year begins on
    day = (day >= 0 ? day : day + 7);
    var daynum = Math.floor((this.getTime() - newYear.getTime() - 
    (this.getTimezoneOffset()-newYear.getTimezoneOffset())*60000)/86400000) + 1;
    var weeknum;
    //if the year starts before the middle of a week
    if(day < 4) {
        weeknum = Math.floor((daynum+day-1)/7) + 1;
        if(weeknum > 52) {
            nYear = new Date(this.getFullYear() + 1,0,1);
            nday = nYear.getDay() - dowOffset;
            nday = nday >= 0 ? nday : nday + 7;
            /*if the next year starts before the middle of
              the week, it is week #1 of that year*/
            weeknum = nday < 4 ? 1 : 53;
        }
    }
    else {
        weeknum = Math.floor((daynum+day-1)/7);
    }
    return weeknum;
};

Here is some code (也尝试过这个),这是特定于周日的(见底部附近)。我还在这里粘贴了相关的片段:

代码语言:javascript
复制
/* For a given date, get the ISO week number
 *
 * Based on information at:
 *
 *    http://www.merlyn.demon.co.uk/weekcalc.htm#WNR
 *
 * Algorithm is to find nearest thursday, it's year
 * is the year of the week number. Then get weeks
 * between that date and the first day of that year.
 *
 * Note that dates in one year can be weeks of previous
 * or next year, overlap is up to 3 days.
 *
 * e.g. 2014/12/29 is Monday in week  1 of 2015
 *      2012/1/1   is Sunday in week 52 of 2011
 */
function getWeekNumber(d) {
    // Copy date so don't modify original
    d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
    // Set to nearest Thursday: current date + 4 - current day number
    // Make Sunday's day number 7
    d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay()||7));
    // Get first day of year
    var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
    // Calculate full weeks to nearest Thursday
    var weekNo = Math.ceil(( ( (d - yearStart) / 86400000) + 1)/7);
    // Return array of year and week number
    return [d.getUTCFullYear(), weekNo];
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-20 21:06:40

算法是使用下一个星期六的星期数。因此,获取下一个星期六,然后使用它的年份作为1月1日。如果不是星期天,则转到前一个星期天。然后从那里得到周数。这听起来可能有点复杂,但它只有几行代码。下面的大部分都是用于游戏的辅助工具。

希望注释足够,getWeekNumber将返回一个[year, weekNumber]数组。针对Mac OS X日历进行了测试,该日历似乎使用了相同的星期编号。请彻底测试,特别是在夏令时转换前后。

代码语言:javascript
复制
/* Get week number in year based on:
 *  - week starts on Sunday
 *  - week number and year is that of the next Saturday,
 *    or current date if it's Saturday
 *    1st week of 2011 starts on Sunday 26 December, 2010
 *    1st week of 2017 starts on Sunday 1 January, 2017
 *
 * Calculations use UTC to avoid daylight saving issues.
 *
 * @param {Date} date - date to get week number of
 * @returns {number[]} year and week number
 */
function getWeekNumber(date) {
  // Copy date as UTC to avoid DST
  var d =  new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
  // Shift to the following Saturday to get the year
  d.setUTCDate(d.getUTCDate() + 6 - d.getUTCDay());
  // Get the first day of the year
  var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
  yearStart.setUTCDate(yearStart.getUTCDate() - yearStart.getUTCDay());
  // Get difference between yearStart and d in milliseconds
  // Reduce to whole weeks
  return [d.getUTCFullYear(), (Math.ceil((d - yearStart) / 6.048e8))];
}

// Helper to format dates
function fDate(d) {
  var opts = {weekday:'short',month:'short',day:'numeric',year:'numeric'};
  return d.toLocaleString(undefined, opts);
}
// Parse yyyy-mm-dd as local
function pDate(s){
  var b = (s+'').split(/\D/);
  var d = new Date(b[0],b[1]-1,b[2]);
  return d.getMonth() == b[1]-1? d : new Date(NaN);
}
// Handle button click
function doButtonClick(){
  var d = pDate(document.getElementById('inp0').value);
  var span = document.getElementById('weekNumber');
  if (isNaN(d)) {
    span.textContent = 'Invalid date';
  } else {
    let [y,w] = getWeekNumber(d);
    span.textContent = `${fDate(d)} is in week ${w} of ${y}`;
  }
}
代码语言:javascript
复制
Date:<input id="inp0" placeholder="yyyy-mm-dd">
<button type="button" onclick="doButtonClick()">Get week number</button><br>
<span id="weekNumber"></span>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52904438

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档