JavaScript - récupère le premier jour de la semaine à partir de la date actuelle

162

J'ai besoin du moyen le plus rapide pour obtenir le premier jour de la semaine. Par exemple: c'est aujourd'hui le 11 novembre et un jeudi; et je veux le premier jour de cette semaine, qui est le 8 novembre, et un lundi. J'ai besoin de la méthode la plus rapide pour la fonction de carte MongoDB, des idées?

EN
la source
Si chaque petite vitesse est cruciale, vous voudrez peut-être tester les performances de ma réponse. J'obtiens un peu de meilleures performances avec les miennes dans les navigateurs (sauf pour IE, qui favorise CMS). Bien sûr, vous devrez le tester avec MongoDB. Lorsque la fonction passe une date qui est lundi, cela devrait être encore plus rapide, car elle ne renvoie que la date d'origine non modifiée.
user113716
J'ai eu le même problème et parce que l'objet de date javascript a beaucoup de bogues, j'utilise maintenant datejs.com (ici code.google.com/p/datejs ), une bibliothèque qui corrige le comportement manquant de la date native.
lolol
Le titre de la question demande le premier jour de la semaine tandis que la description de la question demande la date du dernier lundi. Ce sont en fait deux questions différentes. Vérifiez ma réponse qui résout les deux de manière correcte.
Louis Ameline

Réponses:

323

En utilisant la getDayméthode des objets Date, vous pouvez connaître le numéro de jour de la semaine (étant 0 = dimanche, 1 = lundi, etc.).

Vous pouvez ensuite soustraire ce nombre de jours plus un, par exemple:

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
la source
3
Cette fonction a-t-elle un bogue? - si la date en question est le jeudi 2, jour = 4, diff = 2-4 + 1 = -1, et le résultat de setDate sera «la veille du dernier jour du mois précédent» (voir ceci ).
Izhaki
2
@Izhaki que voulez-vous dire? Pour le 2 mai, la fonction renvoie le 29 avril, ce qui est correct.
meze le
14
Si dimanche est le premier jour de la semaine, utilisez:diff = d.getDate() - day;
cfree
2
Merci pour le code @SMS. J'ai fait une petite torsion pour obtenir exactement 0 heure du premier jour de la semaine. d.setHours(0); d.setMinutes(0); d.setSeconds(0);
Awi
3
au fait, d.setDate est mutable, il change le "d" lui
Ayyash
53

Je ne sais pas comment il se compare pour les performances, mais cela fonctionne.

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

Ou en fonction:

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

setToMonday(new Date());
utilisateur113716
la source
4
Cela aurait dû être la réponse, c'est la seule qui répond à la question posée. Les autres sont bogués ou vous renvoient à des bibliothèques tierces.
OverMars
Cool ça marche pour moi! En faisant quelques ajustements, je suis cool d'obtenir les deux, lundi et vendredi de la semaine à une date donnée!
alexventuraio
10
C'est génial, sauf que cette fonction doit être appelée "setToMonday" car elle modifie l'objet date passé. GetMonday, renverrait une nouvelle Date qui est le lundi en fonction de la date passée. Une différence subtile, mais qui m'a attrapé après avoir utilisé cette fonction. La solution la plus simple consiste à placer date = new Date(date);la première ligne dans la fonction getMonday.
Shane
C'est génial. Une méthode getSunday est encore plus simple! Merci beaucoup!
JesusIsMyDriver.dll
4
Cette réponse est fausse car tous les jours n'ont pas 24 heures à cause des économies de jour. Cela peut changer l'heure de votre date de manière inattendue ou même renvoyer le mauvais jour à certaines occasions.
Louis Ameline
13

Découvrez Date.js

Date.today().previous().monday()
Mat
la source
1
ou peutDate.parse('last monday');
Anurag
J'en ai besoin pour la base de données MongoDB. Je ne peux donc pas référencer date.js, mais merci pour votre extrait de code.
INs
1
Ah, je ne savais pas que vous pouviez exécuter JS directement dans MongoDB. C'est assez lisse. Avait supposé que vous utilisiez le JS pour préparer les données de requête.
Matt
Comme jQuery, pas intéressé par l'extraction d'une bibliothèque entière (aussi petite soit-elle) pour accéder à une fonction simple.
The Muffin Man
Pas une bonne solution, car il y a des pays, leur premier jour de la semaine est le dimanche.
Stefan Brendle le
11

La réponse de CMS est correcte mais suppose que le lundi est le premier jour de la semaine.
La réponse de Chandler Zwolle est correcte mais tripote le prototype Date.
Les autres réponses qui jouent avec les heures / minutes / secondes / millisecondes sont fausses.

La fonction ci-dessous est correcte et prend une date comme premier paramètre et le premier jour de la semaine souhaité comme deuxième paramètre (0 pour dimanche, 1 pour lundi, etc.). Remarque: l'heure, les minutes et les secondes sont mises à 0 pour avoir le début de la journée.

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

Cela fonctionnera bien.

Parth Shah
la source
4

J'utilise ça

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
la source
3

Cette fonction utilise l'heure actuelle en millisecondes pour soustraire la semaine en cours, puis soustrait une semaine de plus si la date actuelle est un lundi (javascript compte à partir du dimanche).

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

Je l'ai testé lorsque la semaine s'étend d'un mois à l'autre (et aussi des années), et il semble fonctionner correctement.

einord
la source
3

Bonsoir,

Je préfère simplement avoir une méthode d'extension simple:

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

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

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

Vous remarquerez que cela utilise en fait une autre méthode d'extension que j'utilise:

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

Maintenant, si vos semaines commencent le dimanche, passez un "0" pour le paramètre pStartOfWeek, comme ceci:

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

De même, si vos semaines commencent le lundi, passez un "1" pour le paramètre pStartOfWeek:

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

Cordialement,

Chandler Zwolle
la source
2

Premier jour de la semaine

Pour obtenir la date du premier jour de la semaine à partir d'aujourd'hui, vous pouvez utiliser quelque chose comme ceci:

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

Ou pour obtenir le dernier jour de la semaine à partir d'aujourd'hui:

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

* Selon votre fuseau horaire, le début de la semaine ne doit pas forcément commencer le dimanche, il peut commencer le vendredi, samedi, lundi ou tout autre jour sur lequel votre machine est réglée. Ces méthodes expliqueront cela.

* Vous pouvez également le formater en utilisant une toISOStringméthode comme celle-ci:getLastSunday().toISOString()

Lior Elrom
la source
1

setDate () a des problèmes avec les limites de mois qui sont notés dans les commentaires ci-dessus. Une solution de contournement propre consiste à trouver la différence de date à l'aide des horodatages d'époque plutôt que des méthodes (étonnamment contre-intuitives) sur l'objet Date. C'est à dire

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
la source
1

Voici ma solution:

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

Vous pouvez maintenant choisir la date par index de tableau renvoyé.

Krystian Wieczorek
la source
0

Un exemple du calcul mathématique uniquement, sans aucune Datefonction.

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
la source
0

une version plus généralisée de ceci ... cela vous donnera n'importe quel jour de la semaine en cours en fonction du jour que vous spécifiez.

//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
la source
-1

Découvrez: moment.js

Exemple:

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: fonctionne aussi avec node.js

pixelfreak
la source
18
Ce n'est pas une réponse à la question d'OP. Il a une date, disons le 08/07/14 (j / m / a). Il veut avoir le premier jour de cette semaine (pour ma région, ce serait le lundi qui vient de passer, ou hier) Une réponse à sa question avec le moment seraitmoment().startOf('week')
Jeroen Pelgrims
Notez que cela moment().startOf("week")peut indiquer la date du dimanche précédent, selon les paramètres régionaux. Dans ce cas, utilisez à la moment().startOf('isoWeek')place: runkit.com/embed/wdpi4bjwh6rt
Harm te Molder
PS Docs sur startOf(): momentjs.com/docs/#/manipulating/start-of
Harm te Molder