简体   繁体   English

如何在Javascript中将周数转换为日期

[英]How to convert a week number to a date in Javascript

I had tried to find some work done but I haven't had luck. 我曾试图找到一些完成的工作,但没有运气。 Any ideas? 有任何想法吗?

Examples: 例子:

Week, 1, 2001 => 2001-01-01 2001年1月1日=> 2001-01-01

Week, 26, 2007 => 2007-06-01 2007年26月,周=> 2007-06-01

As Kevin's code does not implement ISO 8601 properly (first day of the first week of year must be a Monday), I've corrected it and ended up with (also check it on jsfiddle ): 由于Kevin的代码未正确实施ISO 8601(一年的第一周的第一天必须为星期一),因此我对其进行了更正并最终解决了这一问题(也请在jsfiddle上进行检查 ):

function firstDayOfWeek(week, year) { 

    if (year==null) {
        year = (new Date()).getFullYear();
    }

    var date       = firstWeekOfYear(year),
        weekTime   = weeksToMilliseconds(week),
        targetTime = date.getTime() + weekTime;

    return date.setTime(targetTime); 

}

function weeksToMilliseconds(weeks) {
    return 1000 * 60 * 60 * 24 * 7 * (weeks - 1);
}

function firstWeekOfYear(year) {
    var date = new Date();
    date = firstDayOfYear(date,year);
    date = firstWeekday(date);
    return date;
}

function firstDayOfYear(date, year) {
    date.setYear(year);
    date.setDate(1);
    date.setMonth(0);
    date.setHours(0);
    date.setMinutes(0);
    date.setSeconds(0);
    date.setMilliseconds(0);
    return date;
}

/**
 * Sets the given date as the first day of week of the first week of year.
 */
function firstWeekday(firstOfJanuaryDate) {
    // 0 correspond au dimanche et 6 correspond au samedi.
    var FIRST_DAY_OF_WEEK = 1; // Monday, according to iso8601
    var WEEK_LENGTH = 7; // 7 days per week
    var day = firstOfJanuaryDate.getDay();
    day = (day === 0) ? 7 : day; // make the days monday-sunday equals to 1-7 instead of 0-6
    var dayOffset=-day+FIRST_DAY_OF_WEEK; // dayOffset will correct the date in order to get a Monday
    if (WEEK_LENGTH-day+1<4) {
        // the current week has not the minimum 4 days required by iso 8601 => add one week
        dayOffset += WEEK_LENGTH;
    }
    return new Date(firstOfJanuaryDate.getTime()+dayOffset*24*60*60*1000);
}

function assertDateEquals(effectiveDate, expectedDate, description) {
    if ((effectiveDate==null ^ expectedDate==null) || effectiveDate.getTime()!=expectedDate.getTime()) {
        console.log("assert failed: "+description+"; effective="+effectiveDate+", expected="+expectedDate);
    }
}
function assertEquals(effectiveValue, expectedValue, description) {
    if (effectiveValue!=expectedValue) {
        console.log("assert failed: "+description+"; effective="+effectiveValue+", expected="+expectedValue);
    }
}

// expect the first day of year to be a monday
for (var i=1970; i<2050; i++) {
    assertEquals(firstWeekOfYear(i).getDay(), 1, "first day of year "+i+" must be a monday"); // 1=Monday
}

// assert some future first day of first week of year; source: http://www.epochconverter.com/date-and-time/weeknumbers-by-year.php
assertDateEquals(firstWeekOfYear(2013), new Date(Date.parse("Dec 31, 2012")), "2013");
assertDateEquals(firstWeekOfYear(2014), new Date(Date.parse("Dec 30, 2013")), "2014");
assertDateEquals(firstWeekOfYear(2015), new Date(Date.parse("Dec 29, 2014")), "2015");
assertDateEquals(firstWeekOfYear(2016), new Date(Date.parse("Jan 4, 2016")), "2016");
assertDateEquals(firstWeekOfYear(2017), new Date(Date.parse("Jan 2, 2017")), "2017");
assertDateEquals(firstWeekOfYear(2018), new Date(Date.parse("Jan 1, 2018")), "2018");
assertDateEquals(firstWeekOfYear(2019), new Date(Date.parse("Dec 31, 2018")), "2019");
assertDateEquals(firstWeekOfYear(2020), new Date(Date.parse("Dec 30, 2019")), "2020");
assertDateEquals(firstWeekOfYear(2021), new Date(Date.parse("Jan 4, 2021")), "2021");
assertDateEquals(firstWeekOfYear(2022), new Date(Date.parse("Jan 3, 2022")), "2022");
assertDateEquals(firstWeekOfYear(2023), new Date(Date.parse("Jan 2, 2023")), "2023");
assertDateEquals(firstWeekOfYear(2024), new Date(Date.parse("Jan 1, 2024")), "2024");
assertDateEquals(firstWeekOfYear(2025), new Date(Date.parse("Dec 30, 2024")), "2025");
assertDateEquals(firstWeekOfYear(2026), new Date(Date.parse("Dec 29, 2025")), "2026");

console.log("All assertions done.");

I included test cases for some dates to check that the first day of the first week of year is a Monday and checked some dates based on http://www.epochconverter.com/date-and-time/weeknumbers-by-year.php 我提供了一些日期的测试用例,以检查一年中第一周的第一天是星期一,并根据http://www.epochconverter.com/date-and-time/weeknumbers-by-year来检查一些日期。的PHP

Someone might be still interested in a more contained version: 可能有人仍然对一个更加封闭的版本感兴趣:

function firstDayOfWeek (year, week) {

    // Jan 1 of 'year'
    var d = new Date(year, 0, 1),
        offset = d.getTimezoneOffset();

    // ISO: week 1 is the one with the year's first Thursday 
    // so nearest Thursday: current date + 4 - current day number
    // Sunday is converted from 0 to 7
    d.setDate(d.getDate() + 4 - (d.getDay() || 7));

    // 7 days * (week - overlapping first week)
    d.setTime(d.getTime() + 7 * 24 * 60 * 60 * 1000 
        * (week + (year == d.getFullYear() ? -1 : 0 )));

    // daylight savings fix
    d.setTime(d.getTime() 
        + (d.getTimezoneOffset() - offset) * 60 * 1000);

    // back to Monday (from Thursday)
    d.setDate(d.getDate() - 3);

    return d;
}

I took the original idea from Kevin , with some tweaks, coz the original code is returning milliseconds. 我从Kevin那里得到了最初的想法,做了一些调整,因为原始代码返回了毫秒。 Here you go: 干得好:

var d = firstDayOfWeek(9, 2013);

console.log(d.format("yyyy-MM-dd"));

////////////////////////////// Main Code //////////////////////////////
function firstDayOfWeek(week, year) {

    if (typeof year !== 'undefined') {
        year = (new Date()).getFullYear();
    }

    var date       = firstWeekOfYear(year),
        weekTime   = weeksToMilliseconds(week),
        targetTime = date.getTime() + weekTime - 86400000;

    var result = new Date(targetTime)

    return result; 
}

function weeksToMilliseconds(weeks) {
    return 1000 * 60 * 60 * 24 * 7 * (weeks - 1);
}

function firstWeekOfYear(year) {
    var date = new Date();
    date = firstDayOfYear(date,year);
    date = firstWeekday(date);
    return date;
}

function firstDayOfYear(date, year) {
    date.setYear(year);
    date.setDate(1);
    date.setMonth(0);
    date.setHours(0);
    date.setMinutes(0);
    date.setSeconds(0);
    date.setMilliseconds(0);
    return date;
}

function firstWeekday(date) {

    var day = date.getDay(),
        day = (day === 0) ? 7 : day;

    if (day > 3) {

        var remaining = 8 - day,
            target    = remaining + 1;

        date.setDate(target);
    }

    return date;
}

Take a look at this fiddle . 看看这个小提琴 First, it gets the first week of the specified year. 首先,它获得指定年份的第一周。 This takes into account that according to ISO 8601 the first week of the year is the first week containing a wednesday. 考虑到根据ISO 8601 ,一年的第一周是包含星期三的第一周。 Then it adds the weeks to the acquired date and returns the result. 然后将星期数添加到获取的日期并返回结果。

function firstDayOfWeek(week, year) {

    var date       = firstWeekOfYear(year),
        weekTime   = weeksToMilliseconds(week),
        targetTime = weekTime + date.getTime();

    return date.setTime(targetTime);

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM