JavaScript: obtenga el primer día de la semana a partir de la fecha actual


162

Necesito la forma más rápida de obtener el primer día de la semana. Por ejemplo: hoy es 11 de noviembre y jueves; y quiero el primer día de esta semana, que es el 8 de noviembre, y un lunes. Necesito el método más rápido para la función de mapa MongoDB, ¿alguna idea?


Si cada pequeño bit de velocidad es crucial, es posible que desee probar mi respuesta de rendimiento. Estoy obteniendo un rendimiento un poco mejor con el mío en los navegadores (a excepción de IE, que favorece a CMS). Por supuesto, necesitaría probarlo con MongoDB. Cuando la función pasa una fecha que es lunes, debería ser aún más rápida, ya que solo devuelve la fecha original sin modificar.
user113716

Tengo el mismo problema y porque el objeto de fecha de JavaScript tiene muchos errores que estoy usando ahora datejs.com (aquí code.google.com/p/datejs ), una biblioteca que corrige el comportamiento de la fecha nativa.
lolol

El título de la pregunta solicita el primer día de la semana, mientras que la descripción de la pregunta solicita la fecha del último lunes. Estas son en realidad dos preguntas diferentes. Comprueba mi respuesta que los resuelve a ambos de manera correcta.
Louis Ameline

Respuestas:


323

Usando el getDaymétodo de objetos Date, puede saber la cantidad de días de la semana (siendo 0 = domingo, 1 = lunes, etc.).

Luego puede restar ese número de días más uno, por ejemplo:

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
¿Esta función tiene un error? - si la fecha en cuestión es el jueves 2, día = 4, diff = 2 - 4 + 1 = -1, y el resultado de setDate será 'el día anterior al último día del mes anterior' (vea esto ).
Izhaki

2
@Izhaki, ¿qué quieres decir? Para el 2 de mayo, la función devuelve el 29 de abril, lo cual es correcto.
meze

14
Si el domingo es el primer día de la semana, use:diff = d.getDate() - day;
cfree

2
Gracias por el código @SMS. Hice un pequeño giro para obtener exactamente 0 horas del primer día de la semana. d.setHours(0); d.setMinutes(0); d.setSeconds(0);
Awi

3
por cierto, d.setDate es mutable, cambia la "d" en sí
Ayyash

53

No estoy seguro de cómo se compara el rendimiento, pero esto funciona.

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 como una función:

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

setToMonday(new Date());

44
Esta debería haber sido la respuesta, es la única que responde la pregunta formulada. Los otros tienen errores o lo remiten a bibliotecas de terceros.
OverMars

¡Genial, funciona para mí! Al hacer algunos ajustes, me sale bien, ¡lunes y viernes de la semana a partir de una fecha determinada!
alexventuraio

10
Esto es genial, excepto que esta función debería llamarse "setToMonday" ya que modifica el objeto de fecha pasado. GetMonday, devolvería una nueva Fecha que es el lunes en función de la fecha pasada. Una diferencia sutil, pero que me atrapó después de usar esta función. La solución más fácil es colocarla date = new Date(date);como la primera línea en la función getMonday.
Shane

Esto es asombroso ¡Un método getSunday es aún más fácil! ¡Gracias un montón!
JesusIsMyDriver.dll

44
Esta respuesta es incorrecta porque no todos los días tienen 24 horas debido a los ahorros diurnos. Puede cambiar la hora de su fecha inesperadamente o incluso regresar el día equivocado en ciertas ocasiones.
Louis Ameline

13

Echa un vistazo a Date.js

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

1
o tal vezDate.parse('last monday');
Anurag

Lo necesito para la base de datos MongoDB. Así que no puedo hacer referencia a date.js, pero gracias por tu fragmento de código.
INs

1
Ah, no sabía que pudieras ejecutar JS directamente en MongoDB. Eso es bastante hábil. Había asumido que estaba usando el JS para preparar los datos de la consulta.
Matt

Al igual que jQuery, no está interesado en desplegar una biblioteca completa (no importa cuán pequeña) para obtener acceso a una función simple.
The Muffin Man

No es una buena solución, porque hay países, su primer día de la semana es el domingo.
Stefan Brendle

11

La respuesta de CMS es correcta, pero supone que el lunes es el primer día de la semana.
La respuesta de Chandler Zwolle es correcta pero juega con el prototipo Date.
Otras respuestas que juegan con horas / minutos / segundos / milisegundos son incorrectas.

La siguiente función es correcta y toma una fecha como primer parámetro y el primer día de la semana deseado como segundo parámetro (0 para el domingo, 1 para el lunes, etc.). Nota: la hora, los minutos y los segundos están configurados en 0 para que comience el día.

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

Esto funcionará bien.


4

Estoy usando esto

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

Esta función usa el tiempo de milisegundos actual para restar la semana actual, y luego resta una semana más si la fecha actual es un lunes (javascript cuenta desde el domingo).

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

Lo he probado cuando la semana se extiende de un mes a otro (y también años), y parece funcionar correctamente.


3

Buena noches,

Prefiero tener un método de extensión simple:

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

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

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

Notarás que esto realmente utiliza otro método de extensión que yo uso:

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

Ahora, si sus semanas comienzan el domingo, pase un "0" para el parámetro pStartOfWeek, así:

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

Del mismo modo, si sus semanas comienzan el lunes, pase un "1" para el parámetro pStartOfWeek:

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

Saludos,


2

Primer día de la semana

Para obtener la fecha del primer día de la semana a partir de hoy, puede usar algo como esto:

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 para obtener el último día de la semana a partir de hoy:

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

* Dependiendo de su zona horaria, el comienzo de la semana no tiene que comenzar el domingo, puede comenzar el viernes, sábado, lunes o cualquier otro día en que su máquina esté configurada. Esos métodos darán cuenta de eso.

* También puede formatearlo usando un toISOStringmétodo como este:getLastSunday().toISOString()


1

setDate () tiene problemas con los límites de los meses que se mencionan en los comentarios anteriores. Una solución alternativa clara es encontrar la diferencia de fecha usando marcas de tiempo de época en lugar de los métodos (sorprendentemente contradictorios) en el objeto Fecha. Es decir

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

Aquí está mi solución:

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

Ahora puede elegir la fecha por índice de matriz devuelto.


0

Un ejemplo del cálculo matemáticamente único, sin ninguna Datefunción.

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 versión más generalizada de esto ... esto le dará cualquier día de la semana actual según el día que especifique.

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

Echa un vistazo: moment.js

Ejemplo:

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: también funciona con node.js


18
Sin embargo, esa no es una respuesta a la pregunta de OP. Tiene una cita, digamos 07/08/14 (d / m / a). Quiere obtener el primer día de esta semana (para mi localidad, este sería el lunes que acaba de pasar, o ayer). Una respuesta a su pregunta en este momento seríamoment().startOf('week')
Jeroen Pelgrims

Tenga en cuenta que moment().startOf("week")puede dar la fecha del domingo anterior, dependiendo de la configuración regional. En ese caso, use moment().startOf('isoWeek')en su lugar: runkit.com/embed/wdpi4bjwh6rt
Harm te Molder

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.