Как мне получить текущий номер недели года, как в PHP date('W')
?
Это должен быть номер недели в году по ISO-8601 , недели начинаются с понедельника.
javascript
date
PeeHaa
источник
источник
Ответы:
Вы можете получить то, что хотите здесь:
http://www.merlyn.demon.co.uk/js-date6.htm#YWD.Лучшая ссылка на том же сайте:
Работа с неделями.редактировать
Вот код, основанный на предоставленных ссылках и опубликованных ранее Dommer. Он был слегка протестирован против результатов на
http://www.merlyn.demon.co.uk/js-date6.htm#YWD. Пожалуйста, проверьте внимательно, никаких гарантий не предоставляется.Редактировать 2017
Возникла проблема с датами в период перехода на летнее время и годами, когда 1 января было пятницей. Исправлено с использованием всех методов UTC. Следующее возвращает идентичные результаты в Moment.js.
/* 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]; } 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());
Раздел тестирования
В этом разделе вы можете ввести любую дату в формате ГГГГ-ММ-ДД и убедиться, что этот код дает тот же номер недели, что и номер недели Moment.js ISO (проверено более 50 лет с 2000 по 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>
источник
d.setMilliseconds(0)
- он продолжал показывать разные номера недель для одной и той же даты в зависимости от того, использовал ли я новую дату () или новую дату («1/4/2016»). Просто предупреждение для других, кто может испытать то же самое.Вы также можете использовать библиотеку momentjs:
moment().format('W')
источник
moment().week()
Не номер недели 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 );
источник
(now.getTime() - onejan.getTime())
чтобы избежать проблем со сборкой.Соответственно 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); };
источник
Date.format()
Библиотека Джейкоба Райта реализует форматирование даты в стиле функции PHPdate()
и поддерживает номер недели ISO-8601:new Date().format('W');
Это может быть немного излишним для всего номера недели, но он поддерживает форматирование в стиле PHP и очень удобен, если вы будете делать это много.
источник
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
источник
Я нашел полезным класс Java SE SimpleDateFormat, описанный в спецификации Oracle: http://goo.gl/7MbCh5 . В моем случае в Google Apps Script это работало так:
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); }
источник
Это добавляет метод 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); };
источник
new Date(Date.UTC(2018,11, 31)).getWeek(1)+1
(понедельник - первый день недели в Германии).Получить номер недели любой заданной даты
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 );
источник
I need the week to begin on a Sunday
; Я думаю, что единственное необходимое изменение - это заменить функцию weekday ().getDay()+1
на.getDay()
Код ниже вычисляет правильный номер недели по ISO 8601. Он соответствует PHP
date("W")
за каждую неделю между 01.01.1970 и 01.01.21./** * 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); }
Источник: Тако ван ден Брук
Если вы не занимаетесь расширением прототипов, то вот функция:
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
источник
+6 ) % 7
делает эта часть. Спасибо от скраба!getDay()
начинается в воскресенье, поэтому, если вы хотите, чтобы он начался в воскресенье, вы можете удалить исправление:var nDay = date.getDay();
javascript date = date instanceof Date ? new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()) : new Date()
Если вы уже участвуете в проекте Angular, вы можете использовать
$filter('date')
.Например:
var myDate = new Date(); var myWeek = $filter('date')(myDate, 'ww');
источник
Фрагмент кода, который мне очень нравится, выглядит следующим образом:
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
это моя дата, для которой мне нужен номер текущей недели.В
+
обращенных даты в числа (работа с машинописью).источник
С Luxon ( https://github.com/moment/luxon ):
import { DateTime } from 'luxon'; const week: number = DateTime.fromJSDate(new Date()).weekNumber;
источник
fromJSDate()
только один из многих. Luxon был создан одним из разработчиков MomentJS, и ожидается, что он будет поддерживаться неограниченное время. На данный момент это или Момент - действительно лучший способ выполнить эту задачу.Вот моя реализация для расчета номера недели в JavaScript. исправлены также смещения летнего и зимнего времени. Я использовал определение недели из этой статьи: ISO 8601
Недели с понедельника по воскресенье, а 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); }
для тестирования я использовал следующие тесты JavaScript в 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); } } } });
источник
Номер этой недели был настоящей головной болью. Большинство скриптов в сети у меня не работали. Они работали большую часть времени, но все они в какой-то момент ломались, особенно когда изменился год, и последняя неделя года внезапно стала первой неделей следующего года и т. Д. Даже фильтр даты Angular показал неверные данные (это была 1-я неделя следующего года, angular дал неделя 53).
Заметка: Примеры предназначены для работы с европейскими неделями (сначала понедельник)!
getWeek ()
Date.prototype.getWeek = function(){ // current week's Thursday var curWeek = new Date(this.getTime()); curWeek.setDay(4); // Get 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); };
Я протестировал это, и, похоже, он работает очень хорошо, но если вы заметите в нем недостаток, сообщите мне.
источник
Я много пытался получить самый короткий код, чтобы получить номер недели в соответствии с 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».источник
Другой вариант на основе библиотеки: используйте
d3-time-format
:const formatter = d3.timeFormat('%U'); const weekNum = formatter(new Date());
источник
Кратчайший обходной путь для 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; }
источник
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);
источник