Moment JS początek i koniec danego miesiąca

96

Muszę obliczyć datę JS na rok = 2014 i miesiąc = 9 (wrzesień 2014).

Próbowałem tego:

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

Oba dzienniki pokazują:

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

Data zakończenia jest poprawna, ale ... dlaczego nie jest data rozpoczęcia?

Fabio B.
źródło

Odpowiedzi:

185

endOfDzieje się tak, ponieważ zmienia pierwotną wartość.

Odpowiedni cytat:

Mutuje pierwotny moment, ustawiając go na koniec jednostki czasu.

Oto przykładowa funkcja, która daje pożądane wyniki:

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

Bibliografia:

klyd
źródło
4
momentjest idempotentny, więc możesz również użyć endDate = moment(starDate).endOf("month") ^. ^
Dziękuję,
1
Oczywiście, w rzeczywistości domyślnym sposobem klonowania obiektu w dokumentacji jest moment(<value>). Zaktualizowałem przykład, aby użyć niektórych krótszych funkcji.
klyd
1
Dziękuję Ci. Spędziłem dwie godziny, próbując dowiedzieć się, dlaczego to nie działa.
Leon
1
po raz pierwszy widziałem słowo idempotent użyte w sieci !! dobra robota naomik
Mike
add(-1,"month")nie działa, gdy jest styczeń, a chcesz otrzymać miesiąc z zeszłego roku.
Akhoy
21

możesz użyć tego bezpośrednio na koniec lub początek miesiąca

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

możesz zmienić format, definiując nowy format

Shakti Jadon
źródło
16

Kiedy używasz .endOf(), mutujesz obiekt, do którego się odwołuje, więc startDatestaje się 30 września

Powinieneś użyć, .clone()aby zrobić jego kopię, zamiast go zmieniać

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
źródło
5

Wypróbuj poniższy kod:

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
źródło
1
powinieneś dodać kontekst do swojego kodu, aby wyjaśnić, dlaczego i jak rozwiąże to problem
ᴄʀᴏᴢᴇᴛ
3

Nie myśl, że istnieje jakaś bezpośrednia metoda na uzyskanie ostatniego dnia, ale możesz zrobić coś takiego:

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
źródło
2

Twoja data początkowa to pierwszy dzień miesiąca, w tym przypadku możemy użyć

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

Mam nadzieję że to pomoże!!

nikhil
źródło
0
var d = new moment();
var startMonth = d.clone().startOf('month');
var endMonth = d.clone().endOf('month');
console.log(startMonth, endMonth);

doc

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

Należy pamiętać, że .clone () jest niezbędna w momentjs, w przeciwnym razie nadpisze wartość. Wydaje się w twoim przypadku.

Bardziej ogólne jest zbieranie dat przypadających między datami.

bharat patel
źródło
-2

Poniższy kod powinien działać:

$('#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
źródło
-2

Wypróbuj poniższy kod:

moment(startDate).startOf('months')
moment(startDate).endOf('months')
sacmii
źródło
2
Witamy w Stack Overflow. Istnieje dziesięć innych odpowiedzi na to pytanie; Byłoby dobrze z twojej strony, gdybyś wyjaśnił, dlaczego twój jest lepszy lub lepszy od innych.
chb
nie daje oczekiwanego o / p
Shyam