How to get list of days in a month with Moment.js

2019-03-12 04:43发布

问题:

Using Moment.js I would like to get all days in a month of specific year in an array. For example:

January-2014:
[
"01-wed",
"02-thr",
"03-fri",
"04-sat"
]

any suggestions? I looked through Moment.js docs but couldn't find anything. The closet I got was this:

moment("2012-02", "YYYY-MM").daysInMonth() 

But this only return an int with total days for specific month not an array with each day.

回答1:

Here's a function that will do the trick (not using Moment, but just vanilla JavaScript):

var getDaysArray = function(year, month) {
  var names = [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ];
  var date = new Date(year, month - 1, 1);
  var result = [];
  while (date.getMonth() == month - 1) {
    result.push(date.getDate() + "-" + names[date.getDay()]);
    date.setDate(date.getDate() + 1);
  }
  return result;
}

For example:

js> getDaysArray(2012,2)
["1-wed", "2-thu", "3-fri", "4-sat", "5-sun", "6-mon", "7-tue",
 "8-wed", "9-thu", "10-fri", "11-sat", "12-sun", "13-mon", "14-tue",
"15-wed", "16-thu", "17-fri", "18-sat", "19-sun", "20-mon", "21-tue", 
"22-wed", "23-thu", "24-fri", "25-sat", "26-sun", "27-mon", "28-tue",
"29-wed"]

ES2015+ version:

const getDaysArray = (year, month) => {
  const names = Object.freeze(
     [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ]);
  const date = new Date(year, month - 1, 1);
  const result = [];
  while (date.getMonth() == month - 1) {
    result.push(`${date.getDate()}-${names[date.getDay()]}`);
    date.setDate(date.getDate() + 1);
  }
  return result;
}

Do note that the solutions above don't zero-pad dates before the 10th, unlike the sample output included in the question. With ES2017+ that's pretty easy to fix:

    result.push(`${date.getDate()}`.padStart(2,'0') + `-${names[date.getDay()]}`);

Doing it in older versions of JS requires rolling your own zero-padding logic, which isn't hard but is also not really the focus of the question.



回答2:

Alternative with momentjs, working for me

function getDaysArrayByMonth() {
  var daysInMonth = moment().daysInMonth();
  var arrDays = [];

  while(daysInMonth) {
    var current = moment().date(daysInMonth);
    arrDays.push(current);
    daysInMonth--;
  }

  return arrDays;
}

And you can check

var schedule = getDaysArrayByMonth();
schedule.forEach(function(item) {
  console.log(item.format("DD/MM"));
});


回答3:

Using also lodash _.times:

var daysInMonth = [];

var monthDate = moment().startOf('month'); // change to a date in the month of interest

_.times(monthDate.daysInMonth(), function (n) {
     daysInMonth.push(monthDate.format('D'));  // your format
     monthDate.add(1, 'day');
});


回答4:

Alternatively you might now use moment range to achieve this :

const month = moment('2012-02', 'YYYY-MM');
const range = moment().range(moment(month).startOf('month'), moment(month).endOf('month'));
const days = range.by('days');

console.log([...days].map(date => date.format('DD-ddd')));


回答5:

Below are two nice functional approaches with no external dependency other than Moment:

const currentMonthDates = new Array(moment().daysInMonth()).fill(null).map((x, i) => moment().startOf('month').add(i, 'days'));
const currentMonthDates = Array.from({length: moment().daysInMonth()}, (x, i) => moment().startOf('month').add(i, 'days'));

This returns an array of Moment objects, you can then run whatever format method on it that you wish.

For further reading Creating and filling Arrays of arbitrary lengths in JavaScript, also note that in the first example you have to fill the array with null before mapping over it, as it is still classed as empty before doing so and therefore the map function would not run.



回答6:

To get days in a month with moment.js i use this one :

  function daysInMonth(month) {
    var count =  moment().month(month).daysInMonth();
    var days = [];
    for (var i = 1; i < count+1; i++) {
      days.push(moment().month(month).date(i));
    }
    return days;
  }

Then to call the function

var days = daysInMonth( moment().month() );


回答7:

As of moment.js version 2.1.0, when you set a date like:

    moment([2012, 0, 31]).month(1).format("YYYY-MM-DD"); // 2012-02-29

Then you just need to parse the date and you have the number of days in a month.