Moment JS Beginn und Ende eines bestimmten Monats


92

Ich muss ein JS-Datum für Jahr = 2014 und Monat = 9 (September 2014) berechnen.

Ich habe es versucht:

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

Beide Protokolle zeigen:

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

Enddatum ist korrekt, aber ... warum ist das Startdatum nicht?

Antworten:


175

Das liegt daran, dass endOfder ursprüngliche Wert mutiert.

Relevantes Zitat:

Mutiert den ursprünglichen Moment, indem er auf das Ende einer Zeiteinheit gesetzt wird.

Hier ist eine Beispielfunktion, mit der Sie die gewünschte Ausgabe erhalten:

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

Verweise:


4
momentist idempotent, so dass Sie auch endDate = moment(starDate).endOf("month") ^ verwenden können. ^
Danke

1
Tatsächlich ist die Standardmethode zum Klonen eines Objekts in der Dokumentation moment(<value>). Das Beispiel wurde aktualisiert, um einige der kürzeren Funktionen zu verwenden.
Klyd

1
Danke dir. Ich habe zwei Stunden lang versucht herauszufinden, warum es nicht funktioniert hat.
Leon

1
Zum ersten Mal habe ich das Wort idempotent im Web gesehen !! gut gemacht naomik
Mike

add(-1,"month")funktioniert nicht, wenn es Januar ist und Sie den Monat des letzten Jahres erhalten möchten.
Akhoy

20

Sie können dies direkt für das End- oder Startdatum des Monats verwenden

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

Sie können das Format ändern, indem Sie ein neues Format definieren


16

Wenn Sie verwenden .endOf(), mutieren Sie das Objekt, auf das es aufgerufen wird, und werden so startDatezum 30. September

Sie sollten verwenden .clone(), um eine Kopie davon zu erstellen, anstatt sie zu ändern

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) 

4

Versuchen Sie den folgenden Code:

const moment=require('moment');
console.log("startDate=>",moment().startOf('month').format("YYYY-DD-MM"));
console.log("endDate=>",moment().endOf('month').format("YYYY-DD-MM"));

1
Sie sollten Ihrem Code einen Kontext hinzufügen, um zu erklären, warum und wie das Problem
dadurch

3

Denken Sie nicht wirklich, dass es eine direkte Methode gibt, um den letzten Tag zu erreichen, aber Sie könnten so etwas tun:

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

2

Ihr Startdatum ist der erste Tag des Monats. In diesem Fall können wir verwenden

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

Hoffe das hilft!!


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

doc


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>


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

Bitte beachten Sie, dass .clone () in bestimmten Momenten wichtig ist, da es sonst den Wert überschreibt. Es scheint in Ihrem Fall.

Es ist allgemeiner, eine Reihe von Daten zu erhalten, die zwischen den Daten liegen.


-1

Der folgende Code sollte funktionieren:

$('#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);

-2

Versuchen Sie den folgenden Code:

moment(startDate).startOf('months')
moment(startDate).endOf('months')

2
Willkommen bei Stack Overflow. Es gibt zehn weitere Antworten auf diese Frage. Es wäre gut von Ihnen zu erklären, warum Ihre besser oder vorzuziehen ist als die anderen.
chb

es gibt nicht erwartet o / p
gkd
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.