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 objectmoment
– Máttheus Spoo
Thanks for the excellent contribution. There was a long time that did not see good and complete answers like this on the site. + 1
– Wallace Maxters