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

后端 未结 11 588
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-14 07:17

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-s         


        
相关标签:
11条回答
  • 2020-12-14 07:40

    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.

    0 讨论(0)
  • 2020-12-14 07:46

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

    var getDaysArray = function(year, month) {
      var monthIndex = month - 1; // 0..11 instead of 1..12
      var names = [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ];
      var date = new Date(year, monthIndex, 1);
      var result = [];
      while (date.getMonth() == monthIndex) {
        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 monthIndex = month - 1
      const names = Object.freeze(
         [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ]);
      const date = new Date(year, monthIndex, 1);
      const result = [];
      while (date.getMonth() == monthIndex) {
        result.push(`${date.getDate()}-${names[date.getDay()]}`);
        date.setDate(date.getDate() + 1);
      }
      return result;
    }
    

    As a side note, you can see that declaring the date const doesn't keep us from mutating it (nor would Object.freeze, used to make the weekday names array immutable, do anything to a Date). We're taking advantage of the mutability here, but if we actually wanted an immutable Date with the language enforcing that immutability in current Javascript, we'd have to go to some length.

    Also 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.

    0 讨论(0)
  • 2020-12-14 07:50

    I think that using the method moment(month).daysInMonth() to get the number of days in a month together with Array.from() to generate the array is the cleaner and performative way.

    const getDaysByMonth = (month) => {
      const daysInMonth = moment(month).daysInMonth();
      return Array.from({length: daysInMonth}, (v, k) => k + 1)
    };
    
    let month = '2019-02';
    console.log(`February => ${getDaysByMonth(month)}`);
    
    month = '2019-06';
    console.log(`June => ${getDaysByMonth(month)}`);
    
    month = '2019-07';
    console.log(`July => ${getDaysByMonth(month)}`);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>

    0 讨论(0)
  • 2020-12-14 07:54
    function getAllDatesOfMonth(date) {
        const mDate = moment(date, "YYYY-MM");
        const daysCount = mDate.daysInMonth();
        return Array(daysCount).fill(null).map((v,index)=>{
            const addDays = index === 0 ? 0 : 1;
            return mDate.add(addDays, 'days').format('YYYY-MM-DD');
        });
    }
    
    0 讨论(0)
  • 2020-12-14 07:55

    Came to this post making a date picker (yeah...) - I went with a similar approach to the top answer but I think the for loop is a bit more intuitive/readable personally. This does use JS 0 based date so 5 = June, 1 = February, etc. - you can just omit the "+1" in the date for 1 based date.

    var getDaysInMonth = function(year, month) {
      var names = [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ];
      var date = new Date(year, month + 1, 0);
      var days = date.getDate();
      var dayList = [];
      for (i = days; days > 0; days--) {      
        date.setDate(date.getDate() + 1);
        dayList.push((dayList.length + 1) + '-' + names[date.getDay()]);
      }
      return dayList;
    }
    
    0 讨论(0)
  • 2020-12-14 08:00

    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.

    0 讨论(0)
提交回复
热议问题