JavaScript - получить первый день недели с текущей даты


162

Мне нужен самый быстрый способ получить первый день недели. Например: сегодня 11 ноября и четверг; и я хочу первый день этой недели, 8 ноября, и понедельник. Мне нужен самый быстрый метод для функции карты MongoDB, есть идеи?


Если важна каждая небольшая скорость, вы можете проверить мой ответ на производительность. Я получаю немного лучшую производительность в браузерах (кроме IE, который поддерживает CMS). Конечно, вам нужно проверить это с MongoDB. Когда функции передают дату, которая является понедельником, она должна быть еще быстрее, поскольку она просто возвращает неизмененную исходную дату.
user113716 11.11.10

У меня возникла та же проблема, и из-за того, что в объекте даты javascript есть много ошибок, я использую сейчас datejs.com (здесь code.google.com/p/datejs ), библиотеку, исправляющую поведение промахов родной даты.
Lolol

В заголовке вопроса указывается первый день недели, а в описании вопроса указывается дата последнего понедельника. На самом деле это два разных вопроса. Проверьте мой ответ, который решает их правильно.
Луи Амелин

Ответы:


323

Используя getDayметод объектов Date, вы можете узнать номер дня недели (0 = воскресенье, 1 = понедельник и т. Д.).

Затем вы можете вычесть это количество дней плюс один, например:

function getMonday(d) {
  d = new Date(d);
  var day = d.getDay(),
      diff = d.getDate() - day + (day == 0 ? -6:1); // adjust when day is sunday
  return new Date(d.setDate(diff));
}

getMonday(new Date()); // Mon Nov 08 2010

3
Есть ли в этой функции ошибка? - если рассматриваемой датой является четверг 2-го числа, день = 4, разность = 2 - 4 + 1 = -1, а результатом setDate будет «день, предшествующий последнему дню предыдущего месяца» (см. это ).
Ижаки,

2
@ Ижаки, что ты имеешь в виду? Для 2 мая функция возвращает 29 апреля, что правильно.
мезе

14
Если воскресенье - первый день недели, используйте:diff = d.getDate() - day;
cfree

2
Спасибо за код @SMS. Я сделал небольшой поворот, чтобы получить ровно 0 часов первого дня недели. d.setHours(0); d.setMinutes(0); d.setSeconds(0);
Ави

3
кстати, d.setDate является изменчивым, он меняет само «d»
Ayyash

53

Не уверен, как это сравнивается по производительности, но это работает.

var today = new Date();
var day = today.getDay() || 7; // Get current day number, converting Sun. to 7
if( day !== 1 )                // Only manipulate the date if it isn't Mon.
    today.setHours(-24 * (day - 1));   // Set the hours to day number minus 1
                                         //   multiplied by negative 24
alert(today); // will be Monday

Или как функция:

# modifies _date_
function setToMonday( date ) {
    var day = date.getDay() || 7;  
    if( day !== 1 ) 
        date.setHours(-24 * (day - 1)); 
    return date;
}

setToMonday(new Date());

4
Это должен был быть ответ, единственный ответивший на заданный вопрос. Другие глючат или направляют вас в сторонние библиотеки.
OverMars

Круто это работает для меня! Внося некоторые изменения, я получаю и понедельник, и пятницу недели с указанной даты!
alexventuraio

10
Это здорово, за исключением того, что эта функция должна называться "setToMonday", так как она изменяет переданный объект даты. GetMonday, возвращает новую дату, которая является понедельником на основе даты, переданной внутрь. Небольшая разница, но та, которая поймала меня после использования эта функция. date = new Date(date);Самое простое решение - поставить в качестве первой строки функцию getMonday.
Шейн

Это круто. Метод getSunday еще проще! Огромное спасибо!
JesusIsMyDriver.dll

4
Этот ответ неверен, потому что не все дни имеют 24 часа из-за дневной экономии. Это может либо неожиданно изменить час вашей даты, либо даже вернуть неправильный день в определенных случаях.
Луи Амелин

13

Проверьте Date.js

Date.today().previous().monday()

1
или, может бытьDate.parse('last monday');
Anurag

Мне это нужно для базы данных MongoDB. Поэтому я не могу ссылаться на date.js, но спасибо за ваш фрагмент кода.
INs

1
Ах, я не знал, что вы можете запустить JS напрямую в MongoDB. Это довольно гладко. Предполагалось, что вы используете JS для подготовки данных запроса.
Мэтт

Как и jQuery, он не заинтересован в сносе целой библиотеки (независимо от ее размера), чтобы получить доступ к одной простой функции.
Ман

Не хорошее решение, потому что есть страны, их первый день недели - воскресенье.
Стефан Брендл

11

Ответ CMS правильный, но предполагается, что понедельник - первый день недели.
Ответ Чендлера Зволле верен, но возится с прототипом Даты.
Другие ответы, которые играют с часами / минутами / секундами / миллисекундами, неверны.

Приведенная ниже функция является правильной и принимает дату в качестве первого параметра и желаемый первый день недели в качестве второго параметра (0 для воскресенья, 1 для понедельника и т. Д.). Примечание: часы, минуты и секунды установлены в 0, чтобы иметь начало дня.

function firstDayOfWeek(dateObject, firstDayOfWeekIndex) {

    const dayOfWeek = dateObject.getDay(),
        firstDayOfWeek = new Date(dateObject),
        diff = dayOfWeek >= firstDayOfWeekIndex ?
            dayOfWeek - firstDayOfWeekIndex :
            6 - dayOfWeek

    firstDayOfWeek.setDate(dateObject.getDate() - diff)
    firstDayOfWeek.setHours(0,0,0,0)

    return firstDayOfWeek
}

// August 18th was a Saturday
let lastMonday = firstDayOfWeek(new Date('August 18, 2018 03:24:00'), 1)

// outputs something like "Mon Aug 13 2018 00:00:00 GMT+0200"
// (may vary according to your time zone)
document.write(lastMonday)


8
var dt = new Date(); // current date of week
var currentWeekDay = dt.getDay();
var lessDays = currentWeekDay == 0 ? 6 : currentWeekDay - 1;
var wkStart = new Date(new Date(dt).setDate(dt.getDate() - lessDays));
var wkEnd = new Date(new Date(wkStart).setDate(wkStart.getDate() + 6));

Это будет хорошо работать.


4

Я использую это

function get_next_week_start() {
   var now = new Date();
   var next_week_start = new Date(now.getFullYear(), now.getMonth(), now.getDate()+(8 - now.getDay()));
   return next_week_start;
}

3

Эта функция использует текущее время в миллисекундах для вычитания текущей недели, а затем вычитает еще одну неделю, если текущая дата в понедельник (javascript отсчитывает с воскресенья).

function getMonday(fromDate) {
    // length of one day i milliseconds
  var dayLength = 24 * 60 * 60 * 1000;

  // Get the current date (without time)
    var currentDate = new Date(fromDate.getFullYear(), fromDate.getMonth(), fromDate.getDate());

  // Get the current date's millisecond for this week
  var currentWeekDayMillisecond = ((currentDate.getDay()) * dayLength);

  // subtract the current date with the current date's millisecond for this week
  var monday = new Date(currentDate.getTime() - currentWeekDayMillisecond + dayLength);

  if (monday > currentDate) {
    // It is sunday, so we need to go back further
    monday = new Date(monday.getTime() - (dayLength * 7));
  }

  return monday;
}

Я проверил это, когда неделя переходит от одного месяца к другому (а также лет), и, кажется, работает правильно.


3

Добрый вечер,

Я предпочитаю просто использовать простой метод расширения:

Date.prototype.startOfWeek = function (pStartOfWeek) {
    var mDifference = this.getDay() - pStartOfWeek;

    if (mDifference < 0) {
        mDifference += 7;
    }

    return new Date(this.addDays(mDifference * -1));
}

Вы заметите, что на самом деле используется другой метод расширения, который я использую:

Date.prototype.addDays = function (pDays) {
    var mDate = new Date(this.valueOf());
    mDate.setDate(mDate.getDate() + pDays);
    return mDate;
};

Теперь, если ваши недели начинаются в воскресенье, передайте «0» для параметра pStartOfWeek, например, так:

var mThisSunday = new Date().startOfWeek(0);

Аналогично, если ваши недели начинаются в понедельник, передайте «1» для параметра pStartOfWeek:

var mThisMonday = new Date().startOfWeek(1);

С Уважением,


2

Воскресенье

Чтобы получить дату первого дня недели с сегодняшнего дня, вы можете использовать что-то вроде этого:

function getUpcomingSunday() {
  const date = new Date();
  const today = date.getDate();
  const dayOfTheWeek = date.getDay();
  const newDate = date.setDate(today - dayOfTheWeek + 7);
  return new Date(newDate);
}

console.log(getUpcomingSunday());

Или получить последний день недели с сегодняшнего дня:

function getLastSunday() {
  const date = new Date();
  const today = date.getDate();
  const dayOfTheWeek = date.getDay();
  const newDate = date.setDate(today - (dayOfTheWeek || 7));
  return new Date(newDate);
}

console.log(getLastSunday());

* В зависимости от вашего часового пояса начало недели не обязательно должно начинаться в воскресенье, оно может начинаться в пятницу, субботу, понедельник или в любой другой день, на который настроено ваше устройство. Эти методы будут учитывать это.

* Вы также можете отформатировать его, используя toISOStringметод так:getLastSunday().toISOString()


1

setDate () имеет проблемы с границами месяца, которые отмечены в комментариях выше. Простой обходной путь - найти разницу в дате, используя метки времени эпохи, а не (на удивление нелогично) методы объекта Date. Т.е.

function getPreviousMonday(fromDate) {
    var dayMillisecs = 24 * 60 * 60 * 1000;

    // Get Date object truncated to date.
    var d = new Date(new Date(fromDate || Date()).toISOString().slice(0, 10));

    // If today is Sunday (day 0) subtract an extra 7 days.
    var dayDiff = d.getDay() === 0 ? 7 : 0;

    // Get date diff in millisecs to avoid setDate() bugs with month boundaries.
    var mondayMillisecs = d.getTime() - (d.getDay() + dayDiff) * dayMillisecs;

    // Return date as YYYY-MM-DD string.
    return new Date(mondayMillisecs).toISOString().slice(0, 10);
}

1

Вот мое решение:

function getWeekDates(){
    var day_milliseconds = 24*60*60*1000;
    var dates = [];
    var current_date = new Date();
    var monday = new Date(current_date.getTime()-(current_date.getDay()-1)*day_milliseconds);
    var sunday = new Date(monday.getTime()+6*day_milliseconds);
    dates.push(monday);
    for(var i = 1; i < 6; i++){
        dates.push(new Date(monday.getTime()+i*day_milliseconds));
    }
    dates.push(sunday);
    return dates;
}

Теперь вы можете выбрать дату по возвращенному индексу массива.


0

Пример только математического расчета, без каких-либо Dateфункций.

const date = new Date();
const ts = +date;

const mondayTS = ts - ts % (60 * 60 * 24 * (7-4) * 1000);

const monday = new Date(mondayTS);
console.log(monday.toISOString(), 'Day:', monday.getDay());

const formatTS = v => new Date(v).toISOString();
const adjust = (v, d = 1) => v - v % (d * 1000);

const d = new Date('2020-04-22T21:48:17.468Z');
const ts = +d; // 1587592097468

const test = v => console.log(formatTS(adjust(ts, v)));

test();                     // 2020-04-22T21:48:17.000Z
test(60);                   // 2020-04-22T21:48:00.000Z
test(60 * 60);              // 2020-04-22T21:00:00.000Z
test(60 * 60 * 24);         // 2020-04-22T00:00:00.000Z
test(60 * 60 * 24 * (7-4)); // 2020-04-20T00:00:00.000Z, monday

// So, what does `(7-4)` mean?
// 7 - days number in the week
// 4 - shifting for the weekday number of the first second of the 1970 year, the first time stamp second.
//     new Date(0)          ---> 1970-01-01T00:00:00.000Z
//     new Date(0).getDay() ---> 4


0

более обобщенная версия этого ... это даст вам любой день текущей недели в зависимости от того, какой день вы укажете.

//returns the relative day in the week 0 = Sunday, 1 = Monday ... 6 = Saturday
function getRelativeDayInWeek(d,dy) {
  d = new Date(d);
  var day = d.getDay(),
      diff = d.getDate() - day + (day == 0 ? -6:dy); // adjust when day is sunday
  return new Date(d.setDate(diff));
}

var monday = getRelativeDayInWeek(new Date(),1);
var friday = getRelativeDayInWeek(new Date(),5);

console.log(monday);
console.log(friday);


-1

Проверьте: moment.js

Пример:

moment().day(-7); // last Sunday (0 - 7)
moment().day(7); // next Sunday (0 + 7)
moment().day(10); // next Wednesday (3 + 7)
moment().day(24); // 3 Wednesdays from now (3 + 7 + 7 + 7)

Бонус: работает и с node.js


18
Это не ответ на вопрос ОП, хотя. У него свидание, скажем, 08/07/14 (д / м / г). Он хочет получить первый день этой недели (для моей страны это будет понедельник, который только что прошел, или вчера) Ответ на его вопрос с мгновением был быmoment().startOf('week')
Йерун Пелгримс

Обратите внимание, что moment().startOf("week")может дать дату предыдущего воскресенья, в зависимости от настроек локали. В этом случае используйте moment().startOf('isoWeek')вместо этого: runkit.com/embed/wdpi4bjwh6rt
Вред Молдера

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.