JavaScript - отримати перший день тижня від поточної дати


161

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


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

У мене виникла та сама проблема, і тому що в об’єкті дати JavaScript є багато помилок, які я використовую зараз datejs.com (тут code.google.com/p/datejs ), бібліотеку, яка виправляє поведінку пропуску рідної дати.
lolol

Заголовок запитання задається в перший день тижня, в той час як в описі питання задається дата останнього понеділка. Це фактично два різні питання. Перевірте мою відповідь, чи правильно їх вирішує обидва.
Луї Амлін

Відповіді:


322

Використовуючи getDayметод об’єктів Дата, ви можете знати кількість днів тижня (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
@Izhaki, що ти маєш на увазі? 2 травня функція повертається 29 квітня, що є правильним.
мезе

14
Якщо неділя є першим днем ​​тижня, використовуйте:diff = d.getDate() - day;
вільно

2
Дякуємо за код @SMS. Я зробив невеликий поворот, щоб отримати рівно 0 годин першого дня тижня. d.setHours(0); d.setMinutes(0); d.setSeconds(0);
Awi

3
до речі, d.setDate є змінним, він змінює сам "d"
Айяш

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
Ця відповідь неправильна, оскільки не всі дні мають цілодобову економію через день. Він може або змінити годину вашої дати несподівано або навіть повернути неправильний день у певні випадки.
Луї Амлін

13

Перевірте Date.js

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

1
а можеDate.parse('last monday');
Анураг

Мені це потрібно для бази даних MongoDB. Тому я не можу вказати date.js, але дякую за фрагмент коду.
INS

1
Ах, я не знав, що ви можете виконати JS безпосередньо в MongoDB. Це досить гладко. Припускав, що ви використовуєте JS для підготовки даних запиту.
Мет

Як і jQuery, не зацікавлений знімати всю бібліотеку (незалежно від того, наскільки мало), щоб отримати доступ до однієї простої функції.
The Muffin Man

Не вдале рішення, бо є країни, їх перший день тижня - неділя.
Стефан Брендле

11

Відповідь CMS правильна, але передбачає, що понеділок - перший день тижня.
Відповідь Чендлера Зволле є правильною, але відповідає прототипу Date.
Інші відповіді, які грають з годиною / хвилинами / секундами / мілісекундами, помилкові.

Нижче наведена функція є правильною і приймає дату як перший параметр, а бажаний перший день тижня як другий параметр (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')
Jeroen Pelgrims

Зауважте, що moment().startOf("week")може вказати дату попередньої неділі, залежно від налаштувань мови. У такому випадку скористайтеся moment().startOf('isoWeek')замість цього: runkit.com/embed/wdpi4bjwh6rt
Шкода

PS Документи на startOf(): momentjs.com/docs/#/manipulating/start-of
Harm te
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.