JavaScript - pobierz pierwszy dzień tygodnia od aktualnej daty

161

Potrzebuję najszybszego sposobu na pierwszy dzień tygodnia. Na przykład: dzisiaj jest 11 listopada i czwartek; i chcę pierwszy dzień tego tygodnia, czyli 8 listopada, i poniedziałek. Potrzebuję najszybszej metody dla funkcji mapy MongoDB, jakieś pomysły?

INs
źródło
Jeśli każda odrobina szybkości jest kluczowa, możesz przetestować moją odpowiedź. Mam trochę lepszą wydajność z moją w przeglądarkach (z wyjątkiem IE, który faworyzuje CMS). Oczywiście musiałbyś to przetestować w MongoDB. Gdy funkcja przekroczy datę, która jest poniedziałek, powinno to być jeszcze szybsze, ponieważ po prostu zwraca niezmodyfikowaną pierwotną datę.
user113716
Mam ten sam problem, a ponieważ obiekt daty javascript ma wiele błędów, używam teraz datejs.com (tutaj code.google.com/p/datejs ), biblioteki, która koryguje zachowanie braku natywnej daty.
lolol
Tytuł pytania dotyczy pierwszego dnia tygodnia, a opis pytania dotyczy ostatniego poniedziałku. W rzeczywistości są to dwa różne pytania. Sprawdź moją odpowiedź, która rozwiązuje oba w prawidłowy sposób.
Louis Ameline,

Odpowiedzi:

322

Korzystając z getDaymetody obiektów Date, możesz poznać numer dnia tygodnia (0 = niedziela, 1 = poniedziałek itd.).

Następnie możesz odjąć tę liczbę dni plus jeden, na przykład:

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
CMS
źródło
3
Czy ta funkcja ma błąd? - jeśli daną datą jest drugi czwartek, dzień = 4, diff = 2 - 4 + 1 = -1, a wynikiem setDate będzie „dzień przed ostatnim dniem poprzedniego miesiąca” (zobacz to ).
Izhaki
2
@Izhaki co masz na myśli? Dla 2 maja funkcja zwraca 29 kwietnia, co jest poprawne.
meze
14
Jeśli niedziela jest pierwszym dniem tygodnia, użyj:diff = d.getDate() - day;
cfree
2
Dzięki za kod @SMS. Zrobiłem mały zwrot, aby uzyskać dokładnie 0 godzin pierwszego dnia tygodnia. d.setHours(0); d.setMinutes(0); d.setSeconds(0);
Awi
3
tak przy okazji, d.setDate jest zmienna, zmienia samo „d”
Ayyash,
53

Nie jestem pewien, jak wypada na tle wydajności, ale to działa.

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

Lub jako funkcja:

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

setToMonday(new Date());
user113716
źródło
4
To powinna być odpowiedź, jedyna, która odpowiada na zadane pytanie. Inne zawierają błędy lub odsyłają do bibliotek stron trzecich.
OverMars
Fajnie, to działa na mnie! Dokonując pewnych korekt, fajnie otrzymuję zarówno poniedziałek, jak i piątek tygodnia z podanej daty!
alexventuraio
10
Jest to świetne, z wyjątkiem tego, że ta funkcja powinna nazywać się „setToMonday”, ponieważ modyfikuje przekazany obiekt daty. GetMonday zwróci nową datę, czyli poniedziałek na podstawie przekazanej daty. Subtelna różnica, ale taka, która mnie złapała po użyciu ta funkcja. Najłatwiejszym rozwiązaniem jest umieszczenie date = new Date(date);jako pierwszej linii w funkcji getMonday.
Shane,
To jest niesamowite. Metoda getSunday jest jeszcze prostsza! Wielkie dzięki!
JesusIsMyDriver.dll
4
Ta odpowiedź jest błędna, ponieważ nie wszystkie dni mają 24 godziny ze względu na oszczędności w ciągu dnia. Może albo nieoczekiwanie zmienić godzinę twojej randki, albo nawet zwrócić zły dzień w niektórych przypadkach.
Louis Ameline,
13

Sprawdź Date.js

Date.today().previous().monday()
Matt
źródło
1
a możeDate.parse('last monday');
Anurag
Potrzebuję go do bazy danych MongoDB. Więc nie mogę odwołać się do date.js, ale dziękuję za fragment kodu.
INs
1
Ach, nie wiedziałem, że możesz wykonać JS bezpośrednio w MongoDB. To całkiem sprytne. Zakładał, że używasz JS do przygotowania danych zapytania.
Matt
Podobnie jak jQuery, nie jest zainteresowany ściąganiem całej biblioteki (bez względu na to, jak mała), aby uzyskać dostęp do jednej prostej funkcji.
The Muffin Man,
Nie jest to dobre rozwiązanie, bo są kraje, ich pierwszy dzień tygodnia to niedziela.
Stefan Brendle
11

Odpowiedź CMS jest prawidłowa, ale zakłada, że ​​poniedziałek jest pierwszym dniem tygodnia.
Odpowiedź Chandlera Zwolle jest poprawna, ale bawi się prototypem Date.
Inne odpowiedzi, które grają z godzinami / minutami / sekundami / milisekundami, są błędne.

Poniższa funkcja jest poprawna i przyjmuje datę jako pierwszy parametr i żądany pierwszy dzień tygodnia jako drugi parametr (0 dla niedzieli, 1 dla poniedziałku itd.). Uwaga: godzina, minuty i sekundy są ustawione na 0, aby rozpocząć dzień.

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)

Louis Ameline
źródło
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));

To zadziała dobrze.

Parth Shah
źródło
4

Używam tego

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;
}
1nstinct
źródło
3

Ta funkcja wykorzystuje bieżący czas milisekund do odejmowania bieżącego tygodnia, a następnie odejmuje jeden tydzień więcej, jeśli bieżąca data wypada w poniedziałek (w języku JavaScript liczy się od niedzieli).

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

Przetestowałem to, gdy tydzień trwa od miesiąca do miesiąca (a także lat) i wydaje się, że działa prawidłowo.

einord
źródło
3

Dobry wieczór,

Wolę mieć prostą metodę rozszerzenia:

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

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

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

Zauważysz, że faktycznie wykorzystuje inną metodę rozszerzenia, której używam:

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

Teraz, jeśli twoje tygodnie rozpoczynają się w niedzielę, podaj „0” dla parametru pStartOfWeek, na przykład:

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

Podobnie, jeśli tygodnie rozpoczynają się w poniedziałek, podaj wartość „1” dla parametru pStartOfWeek:

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

Pozdrowienia,

Chandler Zwolle
źródło
2

Pierwszy dzień tygodnia

Aby uzyskać datę pierwszego dnia tygodnia od dzisiaj, możesz użyć czegoś takiego:

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

Lub aby uzyskać ostatni dzień tygodnia od dzisiaj:

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

* W zależności od strefy czasowej początek tygodnia nie musi zaczynać się w niedzielę, może zaczynać się w piątek, sobotę, poniedziałek lub w inny dzień, na który urządzenie jest ustawione. Te metody to wyjaśnią.

* Możesz również sformatować go za pomocą następującej toISOStringmetody:getLastSunday().toISOString()

Lior Elrom
źródło
1

setDate () ma problemy z granicami miesiąca, które opisano w komentarzach powyżej. Prostym obejściem jest znalezienie różnicy dat przy użyciu datowników epok, a nie (zaskakująco sprzecznych z intuicją) metod w obiekcie Date. To znaczy

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);
}
jtschoonhoven
źródło
1

Oto moje rozwiązanie:

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

Teraz możesz wybrać datę na podstawie zwróconego indeksu tablicy.

Krystian Wieczorek
źródło
0

Przykład obliczenia tylko matematycznego, bez żadnych Datefunkcji.

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

Anton Korneychuk
źródło
0

bardziej uogólniona wersja tego ... da ci to dowolny dzień w bieżącym tygodniu na podstawie tego, który dzień podasz.

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

Andy
źródło
-1

Sprawdź: moment.js

Przykład:

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)

Bonus: działa również z node.js

pixelfreak
źródło
18
Nie jest to jednak odpowiedź na pytanie OP. Ma datę, powiedzmy 08/07/14 (d / m / r). Chce dostać pierwszy dzień tego tygodnia (dla mojego regionu byłby to właśnie miniony poniedziałek lub wczoraj). Odpowiedź na jego pytanie byłaby z chwiląmoment().startOf('week')
Jeroen Pelgrims
Należy pamiętać, moment().startOf("week")że w zależności od ustawień regionalnych może podać datę poprzedniej niedzieli. W takim przypadku użyj moment().startOf('isoWeek')zamiast tego: runkit.com/embed/wdpi4bjwh6rt
Harm te Molder
Dokumenty PS na startOf(): momentjs.com/docs/#/manipulating/start-of
Harm te Molder