像在 PHP 中一样,在 JavaScript 中获取一年中的第几周

发布于 2024-11-09 16:12:49 字数 174 浏览 0 评论 0原文

如何获取一年中的当前周数,如 PHP 的 date('W')

它应该是 ISO-8601 一年中的周数,从周开始周一。

How do I get the current weeknumber of the year, like PHP's date('W')?

It should be the ISO-8601 week number of year, weeks starting on Monday.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(25

笑着哭最痛 2024-11-16 16:12:50

另一个基于库的选项:使用 d3-time-format< /a>:

const formatter = d3.timeFormat('%U');
const weekNum = formatter(new Date());

Another library-based option: use d3-time-format:

const formatter = d3.timeFormat('%U');
const weekNum = formatter(new Date());
_畞蕅 2024-11-16 16:12:50

Angular2+ DatePipe 的最短解决方法,针对 ISO-8601 进行了调整:

import {DatePipe} from "@angular/common";

public rightWeekNum: number = 0;
  
constructor(private datePipe: DatePipe) { }
    
calcWeekOfTheYear(dateInput: Date) {
  let falseWeekNum = parseInt(this.datePipe.transform(dateInput, 'ww'));
  this.rightWeekNum = (dateInput.getDay() == 0) ? falseWeekNumber-1 : falseWeekNumber;
}

Shortest workaround for Angular2+ DatePipe, adjusted for ISO-8601:

import {DatePipe} from "@angular/common";

public rightWeekNum: number = 0;
  
constructor(private datePipe: DatePipe) { }
    
calcWeekOfTheYear(dateInput: Date) {
  let falseWeekNum = parseInt(this.datePipe.transform(dateInput, 'ww'));
  this.rightWeekNum = (dateInput.getDay() == 0) ? falseWeekNumber-1 : falseWeekNumber;
}
过潦 2024-11-16 16:12:50

灵感来自 RobG 的回答

我想要的是给定日期的星期几。所以我的回答只是基于星期几星期日。但你可以选择其他日子(即周一、周二……);

首先,我找到给定日期中的星期日,然后计算星期。

function getStartWeekDate(d = null) {
  const now = d || new Date();
  now.setHours(0, 0, 0, 0);
  const sunday = new Date(now);
  sunday.setDate(sunday.getDate() - sunday.getDay());
  return sunday;
}

function getWeek(date) {
  const sunday = getStartWeekDate(date);
  const yearStart = new Date(Date.UTC(2021, 0, 1));
  const weekNo = Math.ceil((((sunday - yearStart) / 86400000) + 1) / 7);
  return weekNo;
}
// tests
for (let i = 0; i < 7; i++)  {
  let m = 14 + i;
  let x = getWeek(new Date(2021, 2, m));
  console.log('week num: ' + x, x + ' == ' + 11, x == 11, m);
}

for (let i = 0; i < 7; i++)  {
  let m = 21 + i;
  let x = getWeek(new Date(2021, 2, m));
  console.log('week num: ' + x, x + ' == ' + 12, x == 12, 'date day: ' +  m);
}
for (let i = 0; i < 4; i++)  {
  let m = 28 + i;
  let x = getWeek(new Date(2021, 2, m));
  console.log('week num: ' + x, x + ' == ' + 13, x == 13, 'date day: ' + m);
}
for (let i = 0; i < 3; i++)  {
  let m = 1 + i;
  let x = getWeek(new Date(2021, 3, m));
  console.log('week num: ' + x, x + ' == ' + 13, x == 13, 'date day: ' +  m);
}

for (let i = 0; i < 7; i++)  {
  let m = 4 + i;
  let x = getWeek(new Date(2021, 3, m));
  console.log('week num: ' + x, x + ' == ' + 14, x == 14, 'date day: ' +  m);
}

Inspired from RobG's answer.

What I wanted is the day of the week of a given date. So my answer is simply based on the day of the week Sunday. But you can choose the other day (i.e. Monday, Tuesday...);

First I find the Sunday in a given date and then calculate the week.

function getStartWeekDate(d = null) {
  const now = d || new Date();
  now.setHours(0, 0, 0, 0);
  const sunday = new Date(now);
  sunday.setDate(sunday.getDate() - sunday.getDay());
  return sunday;
}

function getWeek(date) {
  const sunday = getStartWeekDate(date);
  const yearStart = new Date(Date.UTC(2021, 0, 1));
  const weekNo = Math.ceil((((sunday - yearStart) / 86400000) + 1) / 7);
  return weekNo;
}
// tests
for (let i = 0; i < 7; i++)  {
  let m = 14 + i;
  let x = getWeek(new Date(2021, 2, m));
  console.log('week num: ' + x, x + ' == ' + 11, x == 11, m);
}

for (let i = 0; i < 7; i++)  {
  let m = 21 + i;
  let x = getWeek(new Date(2021, 2, m));
  console.log('week num: ' + x, x + ' == ' + 12, x == 12, 'date day: ' +  m);
}
for (let i = 0; i < 4; i++)  {
  let m = 28 + i;
  let x = getWeek(new Date(2021, 2, m));
  console.log('week num: ' + x, x + ' == ' + 13, x == 13, 'date day: ' + m);
}
for (let i = 0; i < 3; i++)  {
  let m = 1 + i;
  let x = getWeek(new Date(2021, 3, m));
  console.log('week num: ' + x, x + ' == ' + 13, x == 13, 'date day: ' +  m);
}

for (let i = 0; i < 7; i++)  {
  let m = 4 + i;
  let x = getWeek(new Date(2021, 3, m));
  console.log('week num: ' + x, x + ' == ' + 14, x == 14, 'date day: ' +  m);
}

ら栖息 2024-11-16 16:12:50
import dayJs from 'dayjs';
import isoWeek from 'dayjs/plugin/isoWeek';

dayJs.extend(isoWeek);

/**
 * Get the current week number based on date.
 *
 * @return {number}
 * @param date
 */
export const getWeekNumberByDate = (date) => dayJs(date).isoWeek();
import dayJs from 'dayjs';
import isoWeek from 'dayjs/plugin/isoWeek';

dayJs.extend(isoWeek);

/**
 * Get the current week number based on date.
 *
 * @return {number}
 * @param date
 */
export const getWeekNumberByDate = (date) => dayJs(date).isoWeek();
烟酉 2024-11-16 16:12:50

根据 https://en.wikipedia.org/wiki/ISO_week_date

一周从星期一开始,到星期日结束。每年的每周都是周四所在的公历年。因此,一年中的第一周始终包含 1 月 4 日。

date-fns getWeek 执行此操作。

可以根据 wiki 的“元旦前后当代日期示例”表进行测试如下:

在 jsfiddle

// html
<script src="https://cdn.jsdelivr.net/npm/[email protected]/cdn.min.js"></script>

result1: <span id="result1"></span><br>
result2: <span id="result2"></span><br>
result3: <span id="result3"></span><br>
result4: <span id="result4"></span><br>
result5: <span id="result5"></span><br>
result6: <span id="result6"></span><br>
result7: <span id="result7"></span><br>
result8: <span id="result8"></span><br>

// js
function getWeek (date) {
  return dateFns.getWeek(date, { weekStartsOn: 1, firstWeekContainsDate: 4 })
}

document.getElementById('result1').innerHTML = getWeek('1977-01-01')
document.getElementById('result2').innerHTML = getWeek('1977-01-02')
document.getElementById('result3').innerHTML = getWeek('1978-01-01')
document.getElementById('result4').innerHTML = getWeek('1978-01-02')
document.getElementById('result5').innerHTML = getWeek('1979-01-01')
document.getElementById('result6').innerHTML = getWeek('1979-01-02')
document.getElementById('result7').innerHTML = getWeek('1980-12-28')
document.getElementById('result8').innerHTML = getWeek('1980-12-29')

results:

  • result1: 53
  • result2: 53
  • result3: 52
  • result4: 1
  • result5: 1
  • result6: 1
  • result7: 52
  • result8: 1

According to https://en.wikipedia.org/wiki/ISO_week_date

Weeks start with Monday and end on Sunday. Each week's year is the Gregorian year in which the Thursday falls. The first week of the year, hence, always contains 4 January.

date-fns getWeek does this.

It can be tested according to wiki's "Examples of contemporary dates around New Year's Day" table as following:

in jsfiddle

// html
<script src="https://cdn.jsdelivr.net/npm/[email protected]/cdn.min.js"></script>

result1: <span id="result1"></span><br>
result2: <span id="result2"></span><br>
result3: <span id="result3"></span><br>
result4: <span id="result4"></span><br>
result5: <span id="result5"></span><br>
result6: <span id="result6"></span><br>
result7: <span id="result7"></span><br>
result8: <span id="result8"></span><br>

// js
function getWeek (date) {
  return dateFns.getWeek(date, { weekStartsOn: 1, firstWeekContainsDate: 4 })
}

document.getElementById('result1').innerHTML = getWeek('1977-01-01')
document.getElementById('result2').innerHTML = getWeek('1977-01-02')
document.getElementById('result3').innerHTML = getWeek('1978-01-01')
document.getElementById('result4').innerHTML = getWeek('1978-01-02')
document.getElementById('result5').innerHTML = getWeek('1979-01-01')
document.getElementById('result6').innerHTML = getWeek('1979-01-02')
document.getElementById('result7').innerHTML = getWeek('1980-12-28')
document.getElementById('result8').innerHTML = getWeek('1980-12-29')

results:

  • result1: 53
  • result2: 53
  • result3: 52
  • result4: 1
  • result5: 1
  • result6: 1
  • result7: 52
  • result8: 1
彡翼 2024-11-16 16:12:50
now = new Date();
today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
firstOfYear = new Date(now.getFullYear(), 0, 1);
numOfWeek = Math.ceil((((today - firstOfYear) / 86400000)-1)/7);
now = new Date();
today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
firstOfYear = new Date(now.getFullYear(), 0, 1);
numOfWeek = Math.ceil((((today - firstOfYear) / 86400000)-1)/7);
不再让梦枯萎 2024-11-16 16:12:49

您应该能够在这里获得您想要的内容:http://www.merlyn.demon.co.uk/js-date6.htm#YWD

同一网站上更好的链接是:工作数周

编辑

这里是一些基于 Dommer 提供的链接和早期发布的代码。它已根据 http://www.merlyn.demon.co.uk/js-date6.htm#YWD 上的结果进行了轻微测试。请彻底测试,不提供任何保证。

编辑 2017 年

遵守夏令时期间以及 1 月 1 日为星期五的年份存在日期问题。通过使用所有 UTC 方法进行修复。以下代码向 Moment.js 返回相同的结果。

/* For a given date, get the ISO week number
 *
 * Based on information at:
 *
 *    THIS PAGE (DOMAIN EVEN) DOESN'T EXIST ANYMORE UNFORTUNATELY
 *    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];
}

var result = getWeekNumber(new Date());
document.write('It\'s currently week ' + result[1] + ' of ' + result[0]);

创建“UTC”日期时,小时数将归零。

最小化原型版本(仅返回周数):

Date.prototype.getWeekNumber = function(){
  var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
  var dayNum = d.getUTCDay() || 7;
  d.setUTCDate(d.getUTCDate() + 4 - dayNum);
  var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
  return Math.ceil((((d - yearStart) / 86400000) + 1)/7)
};

document.write('The current ISO week number is ' + new Date().getWeekNumber());

测试部分

在此部分中,您可以输入 YYYY-MM-DD 格式的任何日期,并检查此代码是否提供与 Moment.js ISO 周数相同的周数(从 2000 年到 2050 年测试了 50 多年)。

Date.prototype.getWeekNumber = function(){
  var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
  var dayNum = d.getUTCDay() || 7;
  d.setUTCDate(d.getUTCDate() + 4 - dayNum);
  var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
  return Math.ceil((((d - yearStart) / 86400000) + 1)/7)
};

function checkWeek() {
  var s = document.getElementById('dString').value;
  var m = moment(s, 'YYYY-MM-DD');
  document.getElementById('momentWeek').value = m.format('W');
  document.getElementById('answerWeek').value = m.toDate().getWeekNumber();      
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

Enter date  YYYY-MM-DD: <input id="dString" value="2021-02-22">
<button onclick="checkWeek(this)">Check week number</button><br>
Moment: <input id="momentWeek" readonly><br>
Answer: <input id="answerWeek" readonly>

You should be able to get what you want here: http://www.merlyn.demon.co.uk/js-date6.htm#YWD.

A better link on the same site is: Working with weeks.

Edit

Here is some code based on the links provided and that posted eariler by Dommer. It has been lightly tested against results at http://www.merlyn.demon.co.uk/js-date6.htm#YWD. Please test thoroughly, no guarantee provided.

Edit 2017

There was an issue with dates during the period that daylight saving was observed and years where 1 Jan was Friday. Fixed by using all UTC methods. The following returns identical results to Moment.js.

/* For a given date, get the ISO week number
 *
 * Based on information at:
 *
 *    THIS PAGE (DOMAIN EVEN) DOESN'T EXIST ANYMORE UNFORTUNATELY
 *    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];
}

var result = getWeekNumber(new Date());
document.write('It\'s currently week ' + result[1] + ' of ' + result[0]);

Hours are zeroed when creating the "UTC" date.

Minimized, prototype version (returns only week-number):

Date.prototype.getWeekNumber = function(){
  var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
  var dayNum = d.getUTCDay() || 7;
  d.setUTCDate(d.getUTCDate() + 4 - dayNum);
  var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
  return Math.ceil((((d - yearStart) / 86400000) + 1)/7)
};

document.write('The current ISO week number is ' + new Date().getWeekNumber());

Test section

In this section, you can enter any date in YYYY-MM-DD format and check that this code gives the same week number as Moment.js ISO week number (tested over 50 years from 2000 to 2050).

Date.prototype.getWeekNumber = function(){
  var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
  var dayNum = d.getUTCDay() || 7;
  d.setUTCDate(d.getUTCDate() + 4 - dayNum);
  var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
  return Math.ceil((((d - yearStart) / 86400000) + 1)/7)
};

function checkWeek() {
  var s = document.getElementById('dString').value;
  var m = moment(s, 'YYYY-MM-DD');
  document.getElementById('momentWeek').value = m.format('W');
  document.getElementById('answerWeek').value = m.toDate().getWeekNumber();      
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

Enter date  YYYY-MM-DD: <input id="dString" value="2021-02-22">
<button onclick="checkWeek(this)">Check week number</button><br>
Moment: <input id="momentWeek" readonly><br>
Answer: <input id="answerWeek" readonly>

简单气质女生网名 2024-11-16 16:12:49

您还可以使用 momentjs 库:

moment().format('W')

You can use momentjs library also:

moment().format('W')

半﹌身腐败 2024-11-16 16:12:49

不是 ISO-8601 周数,但如果搜索引擎无论如何都将您指向这里。

如上所述,但没有类:

let now = new Date();
let onejan = new Date(now.getFullYear(), 0, 1);
let week = Math.ceil((((now.getTime() - onejan.getTime()) / 86400000) + onejan.getDay() + 1) / 7);

console.log(week);

Not ISO-8601 week number but if the search engine pointed you here anyway.

As said above but without a class:

let now = new Date();
let onejan = new Date(now.getFullYear(), 0, 1);
let week = Math.ceil((((now.getTime() - onejan.getTime()) / 86400000) + onejan.getDay() + 1) / 7);

console.log(week);

凉墨 2024-11-16 16:12:49

一致 http://javascript.about.com/library/blweekyear.htm

Date.prototype.getWeek = function() {
  var onejan = new Date(this.getFullYear(), 0, 1);
  var millisecsInDay = 86400000;
  return Math.ceil((((this - onejan) / millisecsInDay) + onejan.getDay() + 1) / 7);
};

let d = new Date(2020,11,30);
for (let i=0; i<14; i++) {
  console.log(`${d.toDateString()} is week ${d.getWeek()}`);
  d.setDate(d.getDate() + 1);
}

Accordily http://javascript.about.com/library/blweekyear.htm

Date.prototype.getWeek = function() {
  var onejan = new Date(this.getFullYear(), 0, 1);
  var millisecsInDay = 86400000;
  return Math.ceil((((this - onejan) / millisecsInDay) + onejan.getDay() + 1) / 7);
};

let d = new Date(2020,11,30);
for (let i=0; i<14; i++) {
  console.log(`${d.toDateString()} is week ${d.getWeek()}`);
  d.setDate(d.getDate() + 1);
}

你在我安 2024-11-16 16:12:49

下面的代码计算正确的 ISO 8601 周数。它与 PHP 的 date("W") 匹配 1/1/1970 到 1/1/2100 之间的每周。

/**
 * Get the ISO week date week number
 */
Date.prototype.getWeek = function () {
  // Create a copy of this date object
  var target = new Date(this.valueOf());

  // ISO week date weeks start on Monday, so correct the day number
  var dayNr = (this.getDay() + 6) % 7;

  // ISO 8601 states that week 1 is the week with the first Thursday of that year
  // Set the target date to the Thursday in the target week
  target.setDate(target.getDate() - dayNr + 3);

  // Store the millisecond value of the target date
  var firstThursday = target.valueOf();

  // Set the target to the first Thursday of the year
  // First, set the target to January 1st
  target.setMonth(0, 1);

  // Not a Thursday? Correct the date to the next Thursday
  if (target.getDay() !== 4) {
    target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7);
  }

  // The week number is the number of weeks between the first Thursday of the year
  // and the Thursday in the target week (604800000 = 7 * 24 * 3600 * 1000)
  return 1 + Math.ceil((firstThursday - target) / 604800000);
}

来源: Taco van den Broek


如果您不喜欢扩展原型,那么这里有一个函数:

function getWeek(date) {
  if (!(date instanceof Date)) date = new Date();

  // ISO week date weeks start on Monday, so correct the day number
  var nDay = (date.getDay() + 6) % 7;

  // ISO 8601 states that week 1 is the week with the first Thursday of that year
  // Set the target date to the Thursday in the target week
  date.setDate(date.getDate() - nDay + 3);

  // Store the millisecond value of the target date
  var n1stThursday = date.valueOf();

  // Set the target to the first Thursday of the year
  // First, set the target to January 1st
  date.setMonth(0, 1);

  // Not a Thursday? Correct the date to the next Thursday
  if (date.getDay() !== 4) {
    date.setMonth(0, 1 + ((4 - date.getDay()) + 7) % 7);
  }

  // The week number is the number of weeks between the first Thursday of the year
  // and the Thursday in the target week (604800000 = 7 * 24 * 3600 * 1000)
  return 1 + Math.ceil((n1stThursday - date) / 604800000);
}

示例用法:

getWeek(); // Returns 37 (or whatever the current week is)
getWeek(new Date('Jan 2, 2011')); // Returns 52
getWeek(new Date('Jan 1, 2016')); // Returns 53
getWeek(new Date('Jan 4, 2016')); // Returns 1

The code below calculates the correct ISO 8601 week number. It matches PHP's date("W") for every week between 1/1/1970 and 1/1/2100.

/**
 * Get the ISO week date week number
 */
Date.prototype.getWeek = function () {
  // Create a copy of this date object
  var target = new Date(this.valueOf());

  // ISO week date weeks start on Monday, so correct the day number
  var dayNr = (this.getDay() + 6) % 7;

  // ISO 8601 states that week 1 is the week with the first Thursday of that year
  // Set the target date to the Thursday in the target week
  target.setDate(target.getDate() - dayNr + 3);

  // Store the millisecond value of the target date
  var firstThursday = target.valueOf();

  // Set the target to the first Thursday of the year
  // First, set the target to January 1st
  target.setMonth(0, 1);

  // Not a Thursday? Correct the date to the next Thursday
  if (target.getDay() !== 4) {
    target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7);
  }

  // The week number is the number of weeks between the first Thursday of the year
  // and the Thursday in the target week (604800000 = 7 * 24 * 3600 * 1000)
  return 1 + Math.ceil((firstThursday - target) / 604800000);
}

Source: Taco van den Broek


If you're not into extending prototypes, then here's a function:

function getWeek(date) {
  if (!(date instanceof Date)) date = new Date();

  // ISO week date weeks start on Monday, so correct the day number
  var nDay = (date.getDay() + 6) % 7;

  // ISO 8601 states that week 1 is the week with the first Thursday of that year
  // Set the target date to the Thursday in the target week
  date.setDate(date.getDate() - nDay + 3);

  // Store the millisecond value of the target date
  var n1stThursday = date.valueOf();

  // Set the target to the first Thursday of the year
  // First, set the target to January 1st
  date.setMonth(0, 1);

  // Not a Thursday? Correct the date to the next Thursday
  if (date.getDay() !== 4) {
    date.setMonth(0, 1 + ((4 - date.getDay()) + 7) % 7);
  }

  // The week number is the number of weeks between the first Thursday of the year
  // and the Thursday in the target week (604800000 = 7 * 24 * 3600 * 1000)
  return 1 + Math.ceil((n1stThursday - date) / 604800000);
}

Sample usage:

getWeek(); // Returns 37 (or whatever the current week is)
getWeek(new Date('Jan 2, 2011')); // Returns 52
getWeek(new Date('Jan 1, 2016')); // Returns 53
getWeek(new Date('Jan 4, 2016')); // Returns 1
╰沐子 2024-11-16 16:12:49

Jacob Wright 的 Date.format() 库以 PHP date() 函数并支持 ISO-8601 周数:

new Date().format('W');

可能是对于一周的数字来说有点大材小用,但它确实支持 PHP 样式格式,如果您要做很​​多这样的事情,它会非常方便。

Jacob Wright's Date.format() library implements date formatting in the style of PHP's date() function and supports the ISO-8601 week number:

new Date().format('W');

It may be a bit overkill for just a week number, but it does support PHP style formatting and is quite handy if you'll be doing a lot of this.

各自安好 2024-11-16 16:12:49
getWeekOfYear: function(date) {
        var target = new Date(date.valueOf()),
            dayNumber = (date.getUTCDay() + 6) % 7,
            firstThursday;

        target.setUTCDate(target.getUTCDate() - dayNumber + 3);
        firstThursday = target.valueOf();
        target.setUTCMonth(0, 1);

        if (target.getUTCDay() !== 4) {
            target.setUTCMonth(0, 1 + ((4 - target.getUTCDay()) + 7) % 7);
        }

        return Math.ceil((firstThursday - target) /  (7 * 24 * 3600 * 1000)) + 1;
    }

以下代码与时区无关(使用 UTC 日期),并根据 https://en.wikipedia.org 工作/wiki/ISO_8601

getWeekOfYear: function(date) {
        var target = new Date(date.valueOf()),
            dayNumber = (date.getUTCDay() + 6) % 7,
            firstThursday;

        target.setUTCDate(target.getUTCDate() - dayNumber + 3);
        firstThursday = target.valueOf();
        target.setUTCMonth(0, 1);

        if (target.getUTCDay() !== 4) {
            target.setUTCMonth(0, 1 + ((4 - target.getUTCDay()) + 7) % 7);
        }

        return Math.ceil((firstThursday - target) /  (7 * 24 * 3600 * 1000)) + 1;
    }

Following code is timezone-independent (UTC dates used) and works according to the https://en.wikipedia.org/wiki/ISO_8601

拿命拼未来 2024-11-16 16:12:49

的周数

function week(year,month,day) {
    function serial(days) { return 86400000*days; }
    function dateserial(year,month,day) { return (new Date(year,month-1,day).valueOf()); }
    function weekday(date) { return (new Date(date)).getDay()+1; }
    function yearserial(date) { return (new Date(date)).getFullYear(); }
    var date = year instanceof Date ? year.valueOf() : typeof year === "string" ? new Date(year).valueOf() : dateserial(year,month,day), 
        date2 = dateserial(yearserial(date - serial(weekday(date-serial(1))) + serial(4)),1,3);
    return ~~((date - date2 + serial(weekday(date2) + 5))/ serial(7));
}

获取任何给定日期示例

console.log(
    week(2016, 06, 11),//23
    week(2015, 9, 26),//39
    week(2016, 1, 1),//53
    week(2016, 1, 4),//1
    week(new Date(2016, 0, 4)),//1
    week("11 january 2016")//2
);

Get the weeknumber of any given Date

function week(year,month,day) {
    function serial(days) { return 86400000*days; }
    function dateserial(year,month,day) { return (new Date(year,month-1,day).valueOf()); }
    function weekday(date) { return (new Date(date)).getDay()+1; }
    function yearserial(date) { return (new Date(date)).getFullYear(); }
    var date = year instanceof Date ? year.valueOf() : typeof year === "string" ? new Date(year).valueOf() : dateserial(year,month,day), 
        date2 = dateserial(yearserial(date - serial(weekday(date-serial(1))) + serial(4)),1,3);
    return ~~((date - date2 + serial(weekday(date2) + 5))/ serial(7));
}

Example

console.log(
    week(2016, 06, 11),//23
    week(2015, 9, 26),//39
    week(2016, 1, 1),//53
    week(2016, 1, 4),//1
    week(new Date(2016, 0, 4)),//1
    week("11 january 2016")//2
);
把昨日还给我 2024-11-16 16:12:49

我发现 Oracle 规范中描述的 Java SE 的 SimpleDateFormat 类很有用:
http://goo.gl/7MbCh5。就我而言,在 Google Apps 脚本中,它的工作方式如下:

function getWeekNumber() {
  var weekNum = parseInt(Utilities.formatDate(new Date(), "GMT", "w"));
  Logger.log(weekNum);
}

例如,在电子表格宏中,您可以检索文件的实际时区:

function getWeekNumber() {
  var weekNum = parseInt(Utilities.formatDate(new Date(), SpreadsheetApp.getActiveSpreadsheet().getSpreadsheetTimeZone(), "w"));
  Logger.log(weekNum);
}

I found useful the Java SE's SimpleDateFormat class described on Oracle's specification:
http://goo.gl/7MbCh5. In my case in Google Apps Script it worked like this:

function getWeekNumber() {
  var weekNum = parseInt(Utilities.formatDate(new Date(), "GMT", "w"));
  Logger.log(weekNum);
}

For example in a spreadsheet macro you can retrieve the actual timezone of the file:

function getWeekNumber() {
  var weekNum = parseInt(Utilities.formatDate(new Date(), SpreadsheetApp.getActiveSpreadsheet().getSpreadsheetTimeZone(), "w"));
  Logger.log(weekNum);
}
心房敞 2024-11-16 16:12:49

这将“getWeek”方法添加到 Date.prototype,该方法返回从年初开始的周数。该参数定义了首先考虑一周中的哪一天。如果没有通过参数,则假定第一天是星期日。

/**
 * Get week number in the year.
 * @param  {Integer} [weekStart=0]  First day of the week. 0-based. 0 for Sunday, 6 for Saturday.
 * @return {Integer}                0-based number of week.
 */
Date.prototype.getWeek = function(weekStart) {
    var januaryFirst = new Date(this.getFullYear(), 0, 1);
    if(weekStart !== undefined && (typeof weekStart !== 'number' || weekStart % 1 !== 0 || weekStart < 0 || weekStart > 6)) {
      throw new Error('Wrong argument. Must be an integer between 0 and 6.');
    }
    weekStart = weekStart || 0;
    return Math.floor((((this - januaryFirst) / 86400000) + januaryFirst.getDay() - weekStart) / 7);
};

This adds "getWeek" method to Date.prototype which returns number of week from the beginning of the year. The argument defines which day of the week to consider the first. If no argument passed, first day is assumed Sunday.

/**
 * Get week number in the year.
 * @param  {Integer} [weekStart=0]  First day of the week. 0-based. 0 for Sunday, 6 for Saturday.
 * @return {Integer}                0-based number of week.
 */
Date.prototype.getWeek = function(weekStart) {
    var januaryFirst = new Date(this.getFullYear(), 0, 1);
    if(weekStart !== undefined && (typeof weekStart !== 'number' || weekStart % 1 !== 0 || weekStart < 0 || weekStart > 6)) {
      throw new Error('Wrong argument. Must be an integer between 0 and 6.');
    }
    weekStart = weekStart || 0;
    return Math.floor((((this - januaryFirst) / 86400000) + januaryFirst.getDay() - weekStart) / 7);
};
哎呦我呸! 2024-11-16 16:12:49

此代码修复了 nvd 回答中的错误

function getWeek(param) {
    let onejan = new Date(param.getFullYear(), 0, 1);
    return Math.ceil((((param.getTime() - onejan.getTime()) / 86400000) + onejan.getDay()) / 7);
}

this code fixes a bug in answer by nvd

function getWeek(param) {
    let onejan = new Date(param.getFullYear(), 0, 1);
    return Math.ceil((((param.getTime() - onejan.getTime()) / 86400000) + onejan.getDay()) / 7);
}
瀞厅☆埖开 2024-11-16 16:12:49

如果您已经在 Angular 项目中,则可以使用 $filter('date')

例如:

var myDate = new Date();
var myWeek = $filter('date')(myDate, 'ww');

If you are already in an Angular project you could use $filter('date').

For example:

var myDate = new Date();
var myWeek = $filter('date')(myDate, 'ww');
梨涡少年 2024-11-16 16:12:49

这周的数字真是令人痛苦。网络上大多数琐碎的解决方案对我来说并不真正有效,因为它们在大部分时间都有效,但它们都在某个时候崩溃了,特别是当年份发生变化并且一年的最后一周突然成为明年的第一周等时。甚至 Angular 的日期过滤器显示的数据不正确(这是明年的第一周,Angular 给出的是第 53 周)。

注意:这些示例设计用于欧洲周(周一优先)!

getWeek()

Date.prototype.getWeek = function(){

    // current week's Thursday
    var curWeek = new Date(this.getTime());
        curWeek.setDay(4);

    // current year's first week's Thursday
    var firstWeek = new Date(curWeek.getFullYear(), 0, 4);
        firstWeek.setDay(4);

    return (curWeek.getDayIndex() - firstWeek.getDayIndex()) / 7 + 1;
};

setDay()

/**
* Make a setDay() prototype for Date
* Sets week day for the date
*/
Date.prototype.setDay = function(day){

    // Get day and make Sunday to 7
    var weekDay = this.getDay() || 7;
    var distance = day - weekDay;
    this.setDate(this.getDate() + distance);

    return this;
}

getDayIndex()

/*
* Returns index of given date (from Jan 1st)
*/

Date.prototype.getDayIndex = function(){
    var start = new Date(this.getFullYear(), 0, 0);
    var diff = this - start;
    var oneDay = 86400000;
    
    return Math.floor(diff / oneDay);
};

我已经测试过这个,它似乎工作得很好,但如果你注意到它有一个缺陷, 请告诉我。

This week number thing has been a real pain in the a**. Most trivial solutions around the web didn't really work for me as they worked most of the time but all of them broke at some point, especially when year changed and last week of the year was suddenly next year's first week etc. Even Angular's date filter showed incorrect data (it was the 1st week of next year, Angular gave week 53).

Note: The examples are designed to work with European weeks (Mon first)!

getWeek()

Date.prototype.getWeek = function(){

    // current week's Thursday
    var curWeek = new Date(this.getTime());
        curWeek.setDay(4);

    // current year's first week's Thursday
    var firstWeek = new Date(curWeek.getFullYear(), 0, 4);
        firstWeek.setDay(4);

    return (curWeek.getDayIndex() - firstWeek.getDayIndex()) / 7 + 1;
};

setDay()

/**
* Make a setDay() prototype for Date
* Sets week day for the date
*/
Date.prototype.setDay = function(day){

    // Get day and make Sunday to 7
    var weekDay = this.getDay() || 7;
    var distance = day - weekDay;
    this.setDate(this.getDate() + distance);

    return this;
}

getDayIndex()

/*
* Returns index of given date (from Jan 1st)
*/

Date.prototype.getDayIndex = function(){
    var start = new Date(this.getFullYear(), 0, 0);
    var diff = this - start;
    var oneDay = 86400000;
    
    return Math.floor(diff / oneDay);
};

I have tested this and it seems to be working very well but if you notice a flaw in it, please let me know.

烟柳画桥 2024-11-16 16:12:49

对我来说效果很好的代码片段是这样的:

var yearStart = +new Date(d.getFullYear(), 0, 1);
var today = +new Date(d.getFullYear(),d.getMonth(),d.getDate());
var dayOfYear = ((today - yearStart + 1) / 86400000);
return Math.ceil(dayOfYear / 7).toString();

注意:
d 是我想要当前周数的日期。
+ 将日期转换为数字(使用 TypeScript)。

The code snippet which works pretty well for me is this one:

var yearStart = +new Date(d.getFullYear(), 0, 1);
var today = +new Date(d.getFullYear(),d.getMonth(),d.getDate());
var dayOfYear = ((today - yearStart + 1) / 86400000);
return Math.ceil(dayOfYear / 7).toString();

Note:
d is my Date for which I want the current week number.
The + converts the Dates into numbers (working with TypeScript).

甜柠檬 2024-11-16 16:12:49

使用 Luxon (https://github.com/moment/luxon) :

import { DateTime } from 'luxon';
const week: number = DateTime.fromJSDate(new Date()).weekNumber;

With Luxon (https://github.com/moment/luxon) :

import { DateTime } from 'luxon';
const week: number = DateTime.fromJSDate(new Date()).weekNumber;
迷鸟归林 2024-11-16 16:12:49

这是我在 JavaScript 中计算周数的实现。还纠正了夏季和冬季时间偏移。
我使用了本文中的周定义: ISO 8601

周是从星期一到星期日, 1 月 4 日始终是一年中的第一周。

// add get week prototype functions
// weeks always start from monday to sunday
// january 4th is always in the first week of the year
Date.prototype.getWeek = function () {
    year = this.getFullYear();
    var currentDotw = this.getWeekDay();
    if (this.getMonth() == 11 && this.getDate() - currentDotw > 28) {
        // if true, the week is part of next year 
        return this.getWeekForYear(year + 1);
    }
    if (this.getMonth() == 0 && this.getDate() + 6 - currentDotw < 4) {
        // if true, the week is part of previous year
        return this.getWeekForYear(year - 1);
    }
    return this.getWeekForYear(year);
}

// returns a zero based day, where monday = 0
// all weeks start with monday
Date.prototype.getWeekDay = function () {
    return  (this.getDay() + 6) % 7;
}

// corrected for summer/winter time
Date.prototype.getWeekForYear = function (year) {
    var currentDotw = this.getWeekDay();
    var fourjan = new Date(year, 0, 4);
    var firstDotw = fourjan.getWeekDay();
    var dayTotal = this.getDaysDifferenceCorrected(fourjan) // the difference in days between the two dates.
    // correct for the days of the week
    dayTotal += firstDotw; // the difference between the current date and the first monday of the first week, 
    dayTotal -= currentDotw; // the difference between the first monday and the current week's monday
    // day total should be a multiple of 7 now
    var weeknumber = dayTotal / 7 + 1; // add one since it gives a zero based week number.
    return weeknumber;
}

// corrected for timezones and offset
Date.prototype.getDaysDifferenceCorrected = function (other) {
    var millisecondsDifference = (this - other);
    // correct for offset difference. offsets are in minutes, the difference is in milliseconds
    millisecondsDifference += (other.getTimezoneOffset()- this.getTimezoneOffset()) * 60000;
    // return day total. 1 day is 86400000 milliseconds, floor the value to return only full days
    return Math.floor(millisecondsDifference / 86400000);
}

为了进行测试,我在 Qunit 中使用了以下 JavaScript 测试

var runweekcompare = function(result, expected) {
    equal(result, expected,'Week nr expected value: ' + expected + ' Actual value: ' + result);
}

test('first week number test', function () {
    expect(5);
    var temp = new Date(2016, 0, 4); // is the monday of the first week of the year
    runweekcompare(temp.getWeek(), 1);
    var temp = new Date(2016, 0, 4, 23, 50); // is the monday of the first week of the year
    runweekcompare(temp.getWeek(), 1);
    var temp = new Date(2016, 0, 10, 23, 50); // is the sunday of the first week of the year
    runweekcompare(temp.getWeek(), 1);
    var temp = new Date(2016, 0, 11, 23, 50); // is the second week of the year
    runweekcompare(temp.getWeek(), 2);
    var temp = new Date(2016, 1, 29, 23, 50); // is the 9th week of the year
    runweekcompare(temp.getWeek(), 9);
});

test('first day is part of last years last week', function () {
    expect(2);
    var temp = new Date(2016, 0, 1, 23, 50); // is the first last week of the previous year
    runweekcompare(temp.getWeek(), 53);
    var temp = new Date(2011, 0, 2, 23, 50); // is the first last week of the previous year
    runweekcompare(temp.getWeek(), 52);
});

test('last  day is part of next years first week', function () {
    var temp = new Date(2013, 11, 30); // is part of the first week of 2014
    runweekcompare(temp.getWeek(), 1);
});

test('summer winter time change', function () {
    expect(2);
    var temp = new Date(2000, 2, 26); 
    runweekcompare(temp.getWeek(), 12);
    var temp = new Date(2000, 2, 27); 
    runweekcompare(temp.getWeek(), 13);
});

test('full 20 year test', function () {
    //expect(20 * 12 * 28 * 2);
    for (i = 2000; i < 2020; i++) {
        for (month = 0; month < 12; month++) {
            for (day = 1; day < 29 ; day++) {
                var temp = new Date(i, month, day);
                var expectedweek = temp.getWeek();
                var temp2 = new Date(i, month, day, 23, 50);
                var resultweek = temp.getWeek();
                equal(expectedweek, Math.round(expectedweek), 'week number whole number expected ' + Math.round(expectedweek) + ' resulted week nr ' + expectedweek);
                equal(resultweek, expectedweek, 'Week nr expected value: ' + expectedweek + ' Actual value: ' + resultweek + ' for year ' + i + ' month ' + month + ' day ' + day);
            }
        }
    }
});

Here is my implementation for calculating the week number in JavaScript. corrected for summer and winter time offsets as well.
I used the definition of the week from this article: ISO 8601

Weeks are from mondays to sunday, and january 4th is always in the first week of the year.

// add get week prototype functions
// weeks always start from monday to sunday
// january 4th is always in the first week of the year
Date.prototype.getWeek = function () {
    year = this.getFullYear();
    var currentDotw = this.getWeekDay();
    if (this.getMonth() == 11 && this.getDate() - currentDotw > 28) {
        // if true, the week is part of next year 
        return this.getWeekForYear(year + 1);
    }
    if (this.getMonth() == 0 && this.getDate() + 6 - currentDotw < 4) {
        // if true, the week is part of previous year
        return this.getWeekForYear(year - 1);
    }
    return this.getWeekForYear(year);
}

// returns a zero based day, where monday = 0
// all weeks start with monday
Date.prototype.getWeekDay = function () {
    return  (this.getDay() + 6) % 7;
}

// corrected for summer/winter time
Date.prototype.getWeekForYear = function (year) {
    var currentDotw = this.getWeekDay();
    var fourjan = new Date(year, 0, 4);
    var firstDotw = fourjan.getWeekDay();
    var dayTotal = this.getDaysDifferenceCorrected(fourjan) // the difference in days between the two dates.
    // correct for the days of the week
    dayTotal += firstDotw; // the difference between the current date and the first monday of the first week, 
    dayTotal -= currentDotw; // the difference between the first monday and the current week's monday
    // day total should be a multiple of 7 now
    var weeknumber = dayTotal / 7 + 1; // add one since it gives a zero based week number.
    return weeknumber;
}

// corrected for timezones and offset
Date.prototype.getDaysDifferenceCorrected = function (other) {
    var millisecondsDifference = (this - other);
    // correct for offset difference. offsets are in minutes, the difference is in milliseconds
    millisecondsDifference += (other.getTimezoneOffset()- this.getTimezoneOffset()) * 60000;
    // return day total. 1 day is 86400000 milliseconds, floor the value to return only full days
    return Math.floor(millisecondsDifference / 86400000);
}

for testing i used the following JavaScript tests in Qunit

var runweekcompare = function(result, expected) {
    equal(result, expected,'Week nr expected value: ' + expected + ' Actual value: ' + result);
}

test('first week number test', function () {
    expect(5);
    var temp = new Date(2016, 0, 4); // is the monday of the first week of the year
    runweekcompare(temp.getWeek(), 1);
    var temp = new Date(2016, 0, 4, 23, 50); // is the monday of the first week of the year
    runweekcompare(temp.getWeek(), 1);
    var temp = new Date(2016, 0, 10, 23, 50); // is the sunday of the first week of the year
    runweekcompare(temp.getWeek(), 1);
    var temp = new Date(2016, 0, 11, 23, 50); // is the second week of the year
    runweekcompare(temp.getWeek(), 2);
    var temp = new Date(2016, 1, 29, 23, 50); // is the 9th week of the year
    runweekcompare(temp.getWeek(), 9);
});

test('first day is part of last years last week', function () {
    expect(2);
    var temp = new Date(2016, 0, 1, 23, 50); // is the first last week of the previous year
    runweekcompare(temp.getWeek(), 53);
    var temp = new Date(2011, 0, 2, 23, 50); // is the first last week of the previous year
    runweekcompare(temp.getWeek(), 52);
});

test('last  day is part of next years first week', function () {
    var temp = new Date(2013, 11, 30); // is part of the first week of 2014
    runweekcompare(temp.getWeek(), 1);
});

test('summer winter time change', function () {
    expect(2);
    var temp = new Date(2000, 2, 26); 
    runweekcompare(temp.getWeek(), 12);
    var temp = new Date(2000, 2, 27); 
    runweekcompare(temp.getWeek(), 13);
});

test('full 20 year test', function () {
    //expect(20 * 12 * 28 * 2);
    for (i = 2000; i < 2020; i++) {
        for (month = 0; month < 12; month++) {
            for (day = 1; day < 29 ; day++) {
                var temp = new Date(i, month, day);
                var expectedweek = temp.getWeek();
                var temp2 = new Date(i, month, day, 23, 50);
                var resultweek = temp.getWeek();
                equal(expectedweek, Math.round(expectedweek), 'week number whole number expected ' + Math.round(expectedweek) + ' resulted week nr ' + expectedweek);
                equal(resultweek, expectedweek, 'Week nr expected value: ' + expectedweek + ' Actual value: ' + resultweek + ' for year ' + i + ' month ' + month + ' day ' + day);
            }
        }
    }
});
纵性 2024-11-16 16:12:49

这是对 Typescript 的轻微修改,它还将返回一周开始和周末的日期。我认为在用户界面中显示这些内容是很常见的,因为人们通常不记得周数。

function getWeekNumber(d: Date) {
  // 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
  const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
  // Calculate full weeks to nearest Thursday
  const weekNo = Math.ceil(
    ((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7
  );

  const weekStartDate = new Date(d.getTime());
  weekStartDate.setUTCDate(weekStartDate.getUTCDate() - 3);

  const weekEndDate = new Date(d.getTime());
  weekEndDate.setUTCDate(weekEndDate.getUTCDate() + 3);

  return [d.getUTCFullYear(), weekNo, weekStartDate, weekEndDate] as const;
}

Here is a slight adaptation for Typescript that will also return the dates for the week start and week end. I think it's common to have to display those in a user interface, since people don't usually remember week numbers.

function getWeekNumber(d: Date) {
  // 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
  const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
  // Calculate full weeks to nearest Thursday
  const weekNo = Math.ceil(
    ((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7
  );

  const weekStartDate = new Date(d.getTime());
  weekStartDate.setUTCDate(weekStartDate.getUTCDate() - 3);

  const weekEndDate = new Date(d.getTime());
  weekEndDate.setUTCDate(weekEndDate.getUTCDate() + 3);

  return [d.getUTCFullYear(), weekNo, weekStartDate, weekEndDate] as const;
}

孤寂小茶 2024-11-16 16:12:49

这是我的打字稿实现,我根据一些日期进行了测试。此实现允许您将一周的第一天设置为任意一天。

//sunday = 0, monday = 1, ...
static getWeekNumber(date: Date, firstDay = 1): number {
  const d = new Date(date.getTime());
  d.setHours(0, 0, 0, 0);

  //Set to first day of the week since it is the same weeknumber
  while(d.getDay() != firstDay){
    d.setDate(d.getDate() - 1);
  }

  const dayOfYear = this.getDayOfYear(d);
  let weken = Math.floor(dayOfYear/7);

  // add an extra week if 4 or more days are in this year.
  const daysBefore = ((dayOfYear % 7) - 1);
  if(daysBefore >= 4){
    weken += 1;
  }

  //if the last 3 days onf the year,it is the first week
  const t = new Date(d.getTime());
  t.setDate(t.getDate() + 3);
  if(t.getFullYear() > d.getFullYear()){
    return 1;
  }
  weken += 1;

  return weken;
}

private static getDayOfYear(date: Date){
  const start = new Date(date.getFullYear(), 0, 0);
  const diff = (date.getTime() - start.getTime()) + ((start.getTimezoneOffset() - date.getTimezoneOffset()) * 60 * 1000);
  const oneDay = 1000 * 60 * 60 * 24;
  const day = Math.floor(diff / oneDay);
  return day;
}

测试:

describe('getWeeknumber', () => {
  it('should be ok for 0 sunday', () => {
    expect(DateUtils.getWeekNumber(new Date(2015, 0, 4), 0)).toBe(1);

    expect(DateUtils.getWeekNumber(new Date(2017, 0, 1), 0)).toBe(1);
    expect(DateUtils.getWeekNumber(new Date(2017, 0, 2), 0)).toBe(1);
    expect(DateUtils.getWeekNumber(new Date(2017, 0, 8), 0)).toBe(2);
    expect(DateUtils.getWeekNumber(new Date(2017, 0, 9), 0)).toBe(2);

    expect(DateUtils.getWeekNumber(new Date(2020, 11, 28), 0)).toBe(53);
    expect(DateUtils.getWeekNumber(new Date(2020, 11, 29), 0)).toBe(53);
    expect(DateUtils.getWeekNumber(new Date(2020, 11, 30), 0)).toBe(53);
    expect(DateUtils.getWeekNumber(new Date(2020, 11, 31), 0)).toBe(53);

    expect(DateUtils.getWeekNumber(new Date(2022, 0, 3), 0)).toBe(1);
  });

  it('should be ok for monday 1 default', () => {
    expect(DateUtils.getWeekNumber(new Date(2015, 0, 4), 1)).toBe(1);

    expect(DateUtils.getWeekNumber(new Date(2017, 0, 1), 1)).toBe(52);
    expect(DateUtils.getWeekNumber(new Date(2017, 0, 2), 1)).toBe(1);
    expect(DateUtils.getWeekNumber(new Date(2017, 0, 8), 1)).toBe(1);
    expect(DateUtils.getWeekNumber(new Date(2017, 0, 9), 1)).toBe(2);

    expect(DateUtils.getWeekNumber(new Date(2020, 11, 28), 1)).toBe(53);
    expect(DateUtils.getWeekNumber(new Date(2020, 11, 29), 1)).toBe(53);
    expect(DateUtils.getWeekNumber(new Date(2020, 11, 30), 1)).toBe(53);
    expect(DateUtils.getWeekNumber(new Date(2020, 11, 31), 1)).toBe(53);

    expect(DateUtils.getWeekNumber(new Date(2022, 0, 3), 1)).toBe(1);
  });
});

This is my typescript implementation which I tested against some dates. This implementation allows you to set the first day of the week to any day.

//sunday = 0, monday = 1, ...
static getWeekNumber(date: Date, firstDay = 1): number {
  const d = new Date(date.getTime());
  d.setHours(0, 0, 0, 0);

  //Set to first day of the week since it is the same weeknumber
  while(d.getDay() != firstDay){
    d.setDate(d.getDate() - 1);
  }

  const dayOfYear = this.getDayOfYear(d);
  let weken = Math.floor(dayOfYear/7);

  // add an extra week if 4 or more days are in this year.
  const daysBefore = ((dayOfYear % 7) - 1);
  if(daysBefore >= 4){
    weken += 1;
  }

  //if the last 3 days onf the year,it is the first week
  const t = new Date(d.getTime());
  t.setDate(t.getDate() + 3);
  if(t.getFullYear() > d.getFullYear()){
    return 1;
  }
  weken += 1;

  return weken;
}

private static getDayOfYear(date: Date){
  const start = new Date(date.getFullYear(), 0, 0);
  const diff = (date.getTime() - start.getTime()) + ((start.getTimezoneOffset() - date.getTimezoneOffset()) * 60 * 1000);
  const oneDay = 1000 * 60 * 60 * 24;
  const day = Math.floor(diff / oneDay);
  return day;
}

Tests:

describe('getWeeknumber', () => {
  it('should be ok for 0 sunday', () => {
    expect(DateUtils.getWeekNumber(new Date(2015, 0, 4), 0)).toBe(1);

    expect(DateUtils.getWeekNumber(new Date(2017, 0, 1), 0)).toBe(1);
    expect(DateUtils.getWeekNumber(new Date(2017, 0, 2), 0)).toBe(1);
    expect(DateUtils.getWeekNumber(new Date(2017, 0, 8), 0)).toBe(2);
    expect(DateUtils.getWeekNumber(new Date(2017, 0, 9), 0)).toBe(2);

    expect(DateUtils.getWeekNumber(new Date(2020, 11, 28), 0)).toBe(53);
    expect(DateUtils.getWeekNumber(new Date(2020, 11, 29), 0)).toBe(53);
    expect(DateUtils.getWeekNumber(new Date(2020, 11, 30), 0)).toBe(53);
    expect(DateUtils.getWeekNumber(new Date(2020, 11, 31), 0)).toBe(53);

    expect(DateUtils.getWeekNumber(new Date(2022, 0, 3), 0)).toBe(1);
  });

  it('should be ok for monday 1 default', () => {
    expect(DateUtils.getWeekNumber(new Date(2015, 0, 4), 1)).toBe(1);

    expect(DateUtils.getWeekNumber(new Date(2017, 0, 1), 1)).toBe(52);
    expect(DateUtils.getWeekNumber(new Date(2017, 0, 2), 1)).toBe(1);
    expect(DateUtils.getWeekNumber(new Date(2017, 0, 8), 1)).toBe(1);
    expect(DateUtils.getWeekNumber(new Date(2017, 0, 9), 1)).toBe(2);

    expect(DateUtils.getWeekNumber(new Date(2020, 11, 28), 1)).toBe(53);
    expect(DateUtils.getWeekNumber(new Date(2020, 11, 29), 1)).toBe(53);
    expect(DateUtils.getWeekNumber(new Date(2020, 11, 30), 1)).toBe(53);
    expect(DateUtils.getWeekNumber(new Date(2020, 11, 31), 1)).toBe(53);

    expect(DateUtils.getWeekNumber(new Date(2022, 0, 3), 1)).toBe(1);
  });
});
那片花海 2024-11-16 16:12:49

我做了很多尝试来获得最短的代码来获得符合 ISO 的周数。

Date.prototype.getWeek=function(){
    var date=new Date(this);
    date.setHours(0,0,0,0);
    return Math.round(((date.setDate(this.getDate()+2-(this.getDay()||7))-date.setMonth(0,4))/8.64e7+3+(date.getDay()||7))/7)+"/"+date.getFullYear();}

变量date对于避免改变原始this是必要的。我使用 setDate()setMonth() 的返回值来省去 getTime() 来节省代码长度,并使用指数数一天的毫秒数,而不是单个元素或带有五个零的数字的乘法。 this 是日期或毫秒数,返回值为String 例如“49/2017”。

I tried a lot to get the shortest code to get the weeknumber ISO-conform.

Date.prototype.getWeek=function(){
    var date=new Date(this);
    date.setHours(0,0,0,0);
    return Math.round(((date.setDate(this.getDate()+2-(this.getDay()||7))-date.setMonth(0,4))/8.64e7+3+(date.getDay()||7))/7)+"/"+date.getFullYear();}

The variable date is necessary to avoid to alter the original this. I used the return values of setDate() and setMonth() to dispense with getTime() to save code length and I used an expontial number for milliseconds of a day instead of a multiplication of single elements or a number with five zeros. this is Date or Number of milliseconds, return value is String e.g. "49/2017".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文