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

时间:2011-09-28 09:06:48

标签: javascript date format utc

我曾试图找到一些工作,但我没有运气。有什么想法吗?

示例:

2001年第1周=> 2001-01-01

2007年第26周=> 2007-06-01

4 个答案:

答案 0 :(得分:11)

由于Kevin的代码没有正确实施ISO 8601(一年中第一周的第一天必须是星期一),我已经纠正了它并最终得到了(check it on 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.");

我在某些日期包含测试用例,以检查一年中第一周的第一天是星期一,并根据http://www.epochconverter.com/date-and-time/weeknumbers-by-year.php检查某些日期

答案 1 :(得分:9)

有人可能仍然对更加包含的版本感兴趣:

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;
}

答案 2 :(得分:0)

看看at this fiddle。首先,它获得指定年份的第一周。这考虑到根据ISO 8601,一年中的第一周是包含星期三的第一周。然后它将周数添加到获取的日期并返回结果。

function firstDayOfWeek(week, year) {

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

    return date.setTime(targetTime);

}

答案 3 :(得分:0)

我从Kevin获取了原始想法,并进行了一些调整,因为原始代码返回毫秒。你走了:

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;
}