JavaScript: ottieni il primo giorno della settimana dalla data corrente


162

Ho bisogno del modo più veloce per ottenere il primo giorno della settimana. Ad esempio: oggi è l'11 novembre e un giovedì; e voglio il primo giorno di questa settimana, che è l'8 novembre, e un lunedì. Ho bisogno del metodo più veloce per la funzione mappa MongoDB, qualche idea?


Se ogni piccola velocità è cruciale, potresti voler testare le prestazioni della mia risposta. Sto ottenendo prestazioni leggermente migliori con il mio nei browser (tranne IE, che favorisce il CMS). Ovviamente, dovresti testarlo con MongoDB. Quando la funzione riceve una data che è lunedì, dovrebbe essere ancora più veloce, poiché restituisce solo la data originale non modificata.
user113716

Ho avuto lo stesso problema e poiché l'oggetto data javascript ha molti bug, sto usando ora datejs.com (qui code.google.com/p/datejs ), una libreria che corregge il comportamento mancante della data nativa.
lolol

Il titolo della domanda richiede il primo giorno della settimana mentre la descrizione della domanda richiede la data dell'ultimo lunedì. Queste sono in realtà due domande diverse. Controlla la mia risposta che risolve entrambi in modo corretto.
Louis Ameline,

Risposte:


323

Usando il getDaymetodo degli oggetti Date, puoi conoscere il numero del giorno della settimana (essendo 0 = domenica, 1 = lunedì, ecc.).

È quindi possibile sottrarre quel numero di giorni più uno, ad esempio:

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
Questa funzione ha un bug? - se la data in questione è giovedì 2, giorno = 4, diff = 2 - 4 + 1 = -1, e il risultato di setDate sarà "il giorno prima dell'ultimo giorno del mese precedente" (vedere questo ).
Izhaki,

2
@Izaki cosa intendi? Per il 2 maggio la funzione restituisce il 29 aprile, che è corretta.
Meze,

14
Se la domenica è il primo giorno della settimana, utilizzare:diff = d.getDate() - day;
cfr.

2
Grazie per il codice @SMS. Ho fatto un piccolo giro per ottenere esattamente 0 ore del primo giorno della settimana. d.setHours(0); d.setMinutes(0); d.setSeconds(0);
Awi,

3
a proposito, d.setDate è modificabile, cambia la "d" stessa
Ayyash,

53

Non sono sicuro di come si confronta per le prestazioni, ma funziona.

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

O come una funzione:

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

setToMonday(new Date());

4
Questa avrebbe dovuto essere la risposta, è l'unica che risponde alla domanda posta. Gli altri sono difettosi o ti rimandano a librerie di terze parti.
OverMars

Fantastico, funziona per me! Apportando alcune modifiche, ottengo entrambi, lunedì e venerdì della settimana da una determinata data!
alexventuraio,

10
Questo è fantastico, tranne per il fatto che questa funzione dovrebbe essere chiamata "setToMonday" in quanto modifica l'oggetto data passato. GetMonday, restituirebbe una nuova data che è il lunedì in base alla data passata. Una differenza sottile, ma che mi ha sorpreso dopo l'uso questa funzione. La soluzione più semplice è quella di inserire date = new Date(date);la prima riga nella funzione getMonday.
Shane,

Questo e spettacolare. Un metodo getSunday è ancora più semplice! Grazie mille!
JesusIsMyDriver.dll,

4
Questa risposta è sbagliata perché non tutti i giorni hanno 24 ore a causa dell'ora legale. Potrebbe cambiare l'ora della tua data in modo imprevisto o persino restituire il giorno sbagliato in determinate occasioni.
Louis Ameline,

13

Dai un'occhiata a Date.js

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

1
o forseDate.parse('last monday');
Anurag l'

Ne ho bisogno per il database MongoDB. Quindi non posso fare riferimento a date.js, ma grazie per lo snippet di codice.
IN

1
Ah, non sapevo che avresti potuto eseguire JS direttamente in MongoDB. È piuttosto elegante. Avevo supposto che stessi utilizzando JS per preparare i dati della query.
Matt

Come jQuery, non interessato a trascinare giù un'intera libreria (non importa quanto piccola) per accedere a una semplice funzione.
The Muffin Man,

Non è una buona soluzione, perché ci sono paesi, il loro primo giorno della settimana è domenica.
Stefan Brendle il

11

La risposta di CMS è corretta ma presume che lunedì sia il primo giorno della settimana.
La risposta di Chandler Zwolle è corretta ma armeggia con il prototipo Date.
Altre risposte che giocano con ora / minuti / secondi / millisecondi sono sbagliate.

La funzione seguente è corretta e accetta una data come primo parametro e il primo giorno della settimana desiderato come secondo parametro (0 per domenica, 1 per lunedì, ecc.). Nota: l'ora, i minuti e i secondi sono impostati su 0 per avere l'inizio della giornata.

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

Funzionerà bene.


4

Sto usando questo

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

Questa funzione utilizza l'ora corrente di millisecondi per sottrarre la settimana corrente, quindi sottrae un'altra settimana se la data corrente è di lunedì (il javascript conta dalla domenica).

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

L'ho provato quando la settimana dura da un mese all'altro (e anche anni) e sembra funzionare correttamente.


3

Buonasera,

Preferisco avere solo un semplice metodo di estensione:

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

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

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

Noterai che questo utilizza effettivamente un altro metodo di estensione che uso:

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

Ora, se le tue settimane iniziano domenica, passa uno "0" per il parametro pStartOfWeek, in questo modo:

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

Allo stesso modo, se le tue settimane iniziano il lunedì, passa un "1" per il parametro pStartOfWeek:

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

Saluti,


2

Primo giorno della settimana

Per ottenere la data del primo giorno della settimana da oggi, puoi usare qualcosa del genere:

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

O per ottenere l'ultimo giorno della settimana da oggi:

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

* A seconda del fuso orario, l'inizio della settimana non deve iniziare domenica, può iniziare venerdì, sabato, lunedì o in qualsiasi altro giorno su cui è impostata la macchina. Quei metodi lo spiegheranno.

* Puoi anche formattarlo usando il toISOStringmetodo in questo modo:getLastSunday().toISOString()


1

setDate () presenta problemi con i limiti del mese che sono stati annotati nei commenti sopra. Una soluzione alternativa è quella di trovare la differenza di data usando i timestamp di epoca piuttosto che i metodi (sorprendentemente controintuitivi) sull'oggetto Date. ie

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

Ecco la mia soluzione:

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

Ora puoi scegliere la data in base all'indice dell'array restituito.


0

Un esempio del calcolo matematicamente unico, senza alcuna Datefunzione.

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

una versione più generalizzata di questo ... questo ti darà ogni giorno della settimana corrente in base al giorno specificato.

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

Scopri: moment.js

Esempio:

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: funziona anche con node.js


18
Questa non è una risposta alla domanda dell'OP. Ha una data, diciamo l'08 / 07/14 (g / m / a). Vuole ricevere il primo giorno di questa settimana (per il mio paese questo sarebbe il lunedì che è appena passato, o ieri) Una risposta alla sua domanda con un momento sarebbemoment().startOf('week')
Jeroen Pelgrims

Si noti che moment().startOf("week")potrebbe indicare la data della domenica precedente, a seconda delle impostazioni internazionali. In tal caso, utilizzare moment().startOf('isoWeek')invece: runkit.com/embed/wdpi4bjwh6rt
Harm te Molder

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.