代码之家  ›  专栏  ›  技术社区  ›  Kraang Prime

在没有附加库的情况下使用JavaScript获取当前一周[所以例子都是错误的]

  •  -1
  • Kraang Prime  · 技术社区  · 7 年前

    enter image description here

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

    下面是其中一个库的可视化演示(它们都有其不精确之处,因为它们通常是根据固定的数字计算一周,然后从那里构建):

    enter image description here

    您可以查看 codepen here 由于项目相当复杂,我有 Date.prototype.getWeek 功能一开始就玩起来容易些。您可以随意交换这里找到的示例中的任何代码,因为它们最终都会在几个月内出现问题。

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

    举个例子,有整整一周的时间共享同一周的数字-所以我不知道怎么做 42 甚至可以是准确的。

    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 (也尝试了这个)这是星期天特定的(见底部附近)。我还在这里贴上了相关的剪贴画:

    /* 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];
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   RobG    7 年前

    算法是使用下一个星期六的周数。所以在下一个星期六,然后用它作为1月1日的年份。如果不是星期天,就转到上一个星期天。然后得到从那里开始的周数。听起来可能有点复杂,但这只是几行代码。以下大部分是游戏的助手。

    希望评论足够了, 返回 [year, weekNumber]

    /* 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}`;
      }
    }
    Date:<input id="inp0" placeholder="yyyy-mm-dd">
    <button type="button" onclick="doButtonClick()">Get week number</button><br>
    <span id="weekNumber"></span>