How to get the last day of a month with Momentjs?

Asked

Viewed 1,988 times

3

I’m using MomentJS and I need to pick up the first and last day of the current month.

Currently, to catch the first day of the month I’m doing so:

 var data_inicial = moment().format('01/MM/YYYY')

So far so good, since every month starts with 01.

But what about in the case of the last day of the month? How can I catch the last day of the month with Momentjs?

2 answers

8


The solution is to use endOf('month'), like your own response indicates.

There is only one detail: this method also changes the time. See in the example below:

 console.log(moment([2018, 8, 19]).endOf('month'))
<script src="https://momentjs.com/downloads/moment.min.js"></script>

In the example above I passed [2018, 8, 19] as a parameter for the moment, to create the date of September 19, 2018 (when this array, months are indexed at zero: January is zero, February is 1, etc., so September is month 8 in this case). If you want the current date, just use moment() parameter-less.

In my case, the exit was "2018-10-01T02:59:59.999Z" (yes October 1st, quite different from expected - but I already explain).

This is because moment() uses the current date/time (19 September 2018) and endOf('month') changes the day to the last of the month (30) and the time to 23:59:59.999, but always using the Timezone of the browser.

In my case, the browser Timezone is America/Sao_Paulo, that is, the resulting date is 2018-09-30T23:59:59.999-03:00 (September 30, 2018 at 23:59:59.999 in São Paulo - the offset -03:00 indicates that we are 3 hours behind UTC). Converting to UTC results in 2018-10-01T02:59:59.999Z (the "Z" at the end indicates that it is in UTC).

When using format() the correct date is returned, because the browser’s Timezone is used to get the date and time values:

 console.log(moment([2018, 8, 19]).endOf('month').format('DD/MM/YYYY HH:mm:ss.SSS'))
<script src="https://momentjs.com/downloads/moment.min.js"></script>

Now the way out is 30/09/2018 23:59:59.999. Last day of the month (September 30) with schedule changed to 23:59:59.999.


How are you just getting the date on format and ignoring the time, this is not a problem.

But if you want to keep the same schedule, just create another one moment and set the time using set and passing the values you want to change (in this case, the time fields):

// data e hora atual
var d1 = moment();

// obter o fim do mês e setar horário para o atual
var d2 = moment().endOf('month').set({
    'hour' : d1.get('hour'),
    'minute' : d1.get('minute'),
    'second' : d1.get('second'),
    'millisecond' : d1.get('millisecond')
});

console.log(d1.format('DD/MM/YYYY HH:mm:ss.SSS'));
console.log(d2.format('DD/MM/YYYY HH:mm:ss.SSS'));
<script src="https://momentjs.com/downloads/moment.min.js"></script>

In that case, d2 will have the date of the last day of the month and the time will be "unchanged" (ie will be equal to the current time of the time when the moment was created).


Bonus

To discover the browser Timezone, use Momentjs Timezone and the function guess(). It has this name because it is not always possible to know precisely the correct Timezone (in documentation explains better).

And for the first day of the month it is also possible to use startOf('month'). But it has a feature similar to endOf, which is to change the time to midnight.

  • Only complementing, another way to adjust the time difference would be to convert to a date object with the .toDate() and then use the .setHours(-1), which would return an object dating from the last time of the previous day (which in the case was 1 October). I believe it has its advantages, in case he will no longer use the date as an object moment

  • 1

    Thanks for the excellent contribution. There was a long time that did not see good and complete answers like this on the site. + 1

2

You can use the method endOf and add the parameter 'month'.

Example:

 moment().endOf('month').format('DD/MM/YYYY')

Browser other questions tagged

You are not signed in. Login or sign up in order to post.