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

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

21 ответ

Решение

С использованием 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

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

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

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

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

getMonday(new Date());

Ответ 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)

Воскресенье

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

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()

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

Date.today().previous().monday()
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));

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

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

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

Возврат с 00:00 понедельника до 00:00 понедельника.

      const now = new Date()
const startOfWeek = new Date(now.getFullYear(), now.getMonth(), now.getDate() - now.getDay() + 1)
const endOfWeek = new Date(now.getFullYear(), now.getMonth(), startOfWeek.getDate() + 7)

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

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

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

С Уважением,

Эта функция использует текущее время в миллисекундах для вычитания текущей недели, а затем вычитает еще одну неделю, если текущая дата в понедельник (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;
}

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

Простое решение для получения первого дня недели.

С помощью этого решения можно установить произвольное начало недели (например, воскресенье = 0, понедельник = 1, вторник = 2 и т. д.).

      function getBeginOfWeek(date = new Date(), startOfWeek = 1) {
    const result = new Date(date);
    while (result.getDay() !== startOfWeek) {
        result.setDate(result.getDate() - 1);
    }
    return result;
}
  • Решение правильно переносится на месяцы (из-заDate.setDate()использовался)
  • За startOfWeek, те же постоянные числа, что и вDate.getDay()может быть использован

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

//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);

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

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

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

Принятый ответ не будет работать для тех, кто запускает код в часовом поясе UTC-XX:XX.

Вот код, который будет работать независимо от часового пояса только для даты. Это не сработает, если вы также предоставите время. Укажите только дату или дату синтаксического анализа и укажите ее в качестве входных данных. Я упомянул различные тестовые примеры в начале кода.

Проверьте: 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

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

Важно различать местное время и UTC. Я хотел найти начало недели в формате UTC, поэтому использовал следующую функцию.

      function start_of_week_utc(date, start_day = 1) {

// Returns the start of the week containing a 'date'. Monday 00:00 UTC is
// considered to be the boundary between adjacent weeks, unless 'start_day' is
// specified. A Date object is returned.

    date = new Date(date);
    const day_of_month = date.getUTCDate();
    const day_of_week = date.getUTCDay();
    const difference_in_days = (
        day_of_week >= start_day
        ? day_of_week - start_day
        : day_of_week - start_day + 7
    );
    date.setUTCDate(day_of_month - difference_in_days);
    date.setUTCHours(0);
    date.setUTCMinutes(0);
    date.setUTCSeconds(0);
    date.setUTCMilliseconds(0);
    return date;
}

Чтобы найти начало недели в данном часовом поясе, сначала добавьте смещение часового пояса к входной дате, а затем вычтите его из выходной даты.

      const local_start_of_week = new Date(
    start_of_week_utc(
        date.getTime() + timezone_offset_ms
    ).getTime() - timezone_offset_ms
);

Пример математического расчета без каких-либо 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

Это однострочное решение работает нормально:

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

      let current_date = new Date();
let days_to_monday = 1 - current_date.getDay();
monday_date = current_date.addDays(days_to_monday);

// https://stackoverflow.com/a/563442/6533037
Date.prototype.addDays = function(days) {
    var date = new Date(this.valueOf());
    date.setDate(date.getDate() + days);
    return date;
}

Работает нормально.

Расширение ответа от @Christian C. Salvadó и информации от @Ayyash (объект изменчив) и @Awi и @Louis Ameline (установите часы на 00:00:00)

Функция может быть такой

      function getMonday(d) {
  var day = d.getDay(),
      diff = d.getDate() - day + (day == 0 ? -6:1); // adjust when day is sunday
  d.setDate(diff);
  d.setHours(0,0,0,0); // set hours to 00:00:00

  return d; // object is mutable no need to recreate object
}

getMonday(new Date())
Другие вопросы по тегам