Moment JS inicio y final del mes dado

94

Necesito calcular una fecha de JS dado año = 2014 y mes = 9 (septiembre de 2014).

Probé esto:

var moment = require('moment');
var startDate = moment( year+'-'+month+'-'+01 + ' 00:00:00' );
            var endDate = startDate.endOf('month');
            console.log(startDate.toDate());
            console.log(endDate.toDate());

Ambos registros muestran:

Tue Sep 30 2014 23:59:59 GMT+0200 (CEST)
Tue Sep 30 2014 23:59:59 GMT+0200 (CEST)

La fecha de finalización es correcta pero ... ¿por qué la fecha de inicio no lo es?

Fabio B.
fuente

Respuestas:

178

Eso es porque endOfmuta el valor original.

Cita relevante:

Muta el momento original configurándolo al final de una unidad de tiempo.

Aquí hay una función de ejemplo que le brinda el resultado que desea:

function getMonthDateRange(year, month) {
    var moment = require('moment');

    // month in moment is 0 based, so 9 is actually october, subtract 1 to compensate
    // array is 'year', 'month', 'day', etc
    var startDate = moment([year, month - 1]);

    // Clone the value before .endOf()
    var endDate = moment(startDate).endOf('month');

    // just for demonstration:
    console.log(startDate.toDate());
    console.log(endDate.toDate());

    // make sure to call toDate() for plain JavaScript date type
    return { start: startDate, end: endDate };
}

Referencias:

klyd
fuente
4
momentes idempotente, por lo que también podría usar endDate = moment(starDate).endOf("month") ^. ^
Gracias
1
Absolutamente, de hecho, la forma predeterminada de clonar un objeto en la documentación es moment(<value>). Se actualizó el ejemplo para usar algunas de las funciones más cortas.
klyd
1
Gracias. Pasé dos horas tratando de averiguar por qué no estaba funcionando.
León
1
¡¡Es la primera vez que veo la palabra idempotente en la web !! bien hecho naomik
Mike
add(-1,"month")no funciona cuando es enero y desea obtener el mes del año pasado.
Akhoy
20

puede usar esto directamente para la fecha de finalización o inicio del mes

new moment().startOf('month').format("YYYY-DD-MM");
new moment().endOf("month").format("YYYY-DD-MM");

puede cambiar el formato definiendo un nuevo formato

Shakti Jadon
fuente
16

Cuando lo usa .endOf(), está mutando el objeto al que se llama, por lo que se startDateconvierte en 30 de septiembre

Debería usar .clone()para hacer una copia en lugar de cambiarlo

var startDate = moment(year + '-' + month + '-' + 01 + ' 00:00:00');
            var endDate = startDate.clone().endOf('month');
            console.log(startDate.toDate());
            console.log(endDate.toDate());

Mon Sep 01 2014 00:00:00 GMT+0700 (ICT) 
Tue Sep 30 2014 23:59:59 GMT+0700 (ICT) 
bakkal
fuente
5

Prueba el siguiente código:

const moment=require('moment');
console.log("startDate=>",moment().startOf('month').format("YYYY-DD-MM"));
console.log("endDate=>",moment().endOf('month').format("YYYY-DD-MM"));
Sanjay Singh
fuente
1
debe agregar algo de contexto con su código para explicar por qué y cómo resolverá el problema
ᴄʀᴏᴢᴇᴛ
3

Realmente no creo que haya algún método directo para obtener el último día, pero podrías hacer algo como esto:

var dateInst = new moment();
/**
 * adding 1 month from the present month and then subtracting 1 day, 
 * So you would get the last day of this month 
 */
dateInst.add(1, 'months').date(1).subtract(1, 'days');
/* printing the last day of this month's date */
console.log(dateInst.format('YYYY MM DD'));
Sandeep Gantait
fuente
2

su fecha de inicio es el primer día del mes, en este caso podemos usar

var endDate = moment(startDate).add(1, 'months').subtract(1, 'days');

¡¡Espero que esto ayude!!

nikhil
fuente
0
var d = new moment();
var startMonth = d.clone().startOf('month');
var endMonth = d.clone().endOf('month');
console.log(startMonth, endMonth);

Doc

IfThenElse
fuente
0

const year = 2014;
const month = 09;

// months start at index 0 in momentjs, so we subtract 1
const startDate = moment([year, month - 1, 01]).format("YYYY-MM-DD");

// get the number of days for this month
const daysInMonth = moment(startDate).daysInMonth();

// we are adding the days in this month to the start date (minus the first day)
const endDate = moment(startDate).add(daysInMonth - 1, 'days').format("YYYY-MM-DD");

console.log(`start date: ${startDate}`);
console.log(`end date:   ${endDate}`);
<script
src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js">
</script>

JSON C11
fuente
0
const dates = getDatesFromDateRange("2014-05-02", "2018-05-12", "YYYY/MM/DD", 1);           
console.log(dates);
// you get the whole from-to date ranges as per parameters
var onlyStartDates = dates.map(dateObj => dateObj["to"]);
console.log(onlyStartDates);
// moreover, if you want only from dates then you can grab by "map" function

function getDatesFromDateRange( startDate, endDate, format, counter ) {
    startDate = moment(startDate, format);
    endDate = moment(endDate, format);

    let dates = [];
    let fromDate = startDate.clone();
    let toDate = fromDate.clone().add(counter, "month").startOf("month").add(-1, "day");
    do {
        dates.push({
            "from": fromDate.format(format),
            "to": ( toDate < endDate ) ? toDate.format(format) : endDate.format(format)
        });
        fromDate = moment(toDate, format).add(1, "day").clone();
        toDate = fromDate.clone().add(counter, "month").startOf("month").add(-1, "day");
    } while ( fromDate < endDate );
    return dates;
}

Tenga en cuenta que .clone () es esencial en momentjs, de lo contrario anulará el valor. Parece en tu caso.

Es más genérico, para obtener un montón de citas que caen entre fechas.

bharat patel
fuente
-1

El siguiente código debería funcionar:

$('#reportrange').daterangepicker({
                startDate: start,
                endDate: end,
                ranges: {
                    'Hoy': [moment(), moment()],
                    'Ayer': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
                    'Ultimos 7 dias': [moment().subtract(6, 'days'), moment()],
                    'Ultimos 30 dias': [moment().subtract(29, 'days'), moment()],
                    'Mes actual': [moment().startOf('month'), moment().endOf('month')],
                    'Ultimo mes': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
                    'Enero': [moment().month(0).startOf('month') , moment().month(0).endOf('month')],
                    'Febrero': [moment().month(1).startOf('month') , moment().month(1).endOf('month')],
                    'Marzo': [moment().month(2).startOf('month') , moment().month(2).endOf('month')],
                    'Abril': [moment().month(3).startOf('month') , moment().month(3).endOf('month')],
                    'Mayo': [moment().month(4).startOf('month') , moment().month(4).endOf('month')],
                    'Junio': [moment().month(5).startOf('month') , moment().month(5).endOf('month')],
                    'Julio': [moment().month(6).startOf('month') , moment().month(6).endOf('month')],
                    'Agosto': [moment().month(7).startOf('month') , moment().month(7).endOf('month')],
                    'Septiembre': [moment().month(8).startOf('month') , moment().month(8).endOf('month')],
                    'Octubre': [moment().month(9).startOf('month') , moment().month(9).endOf('month')],
                    'Noviembre': [moment().month(10).startOf('month') , moment().month(10).endOf('month')],
                    'Diciembre': [moment().month(11).startOf('month') , moment().month(11).endOf('month')]
                }
            }, cb);
enrique ramos
fuente
-2

Prueba el siguiente código:

moment(startDate).startOf('months')
moment(startDate).endOf('months')
sacmii
fuente
2
Bienvenido a Stack Overflow. Hay otras diez respuestas a esta pregunta; Sería bueno de su parte explicar por qué el suyo es mejor o preferible que los demás.
chb
no está dando o / p esperado
Shyam