简体   繁体   English

如何使用 Moment.js 获取一个月中的天数列表

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

Using Moment.js I would like to get all days in a month of specific year in an array.使用 Moment.js 我想在一个数组中获取特定年份一个月中的所有天数。 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.我浏览了 Moment.js 文档,但找不到任何东西。 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.但这只会返回一个整数,其中包含特定月份的总天数,而不是每天的数组。

Here's a function that will do the trick (not using Moment, but just vanilla JavaScript):这是一个可以解决问题的函数(不使用 Moment,而是使用普通的 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 - also hid the array of names behind a closure so it's only initialized once: ES2015+ 版本 - 还将名称数组隐藏在闭包后面,因此它只初始化一次:

const getDaysArray = (function() {
  const names = Object.freeze([ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ]);
  return (year, month) => {
    const monthIndex = month - 1
    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 ).作为旁注,您可以看到声明日期const并不能阻止我们对其进行变异( Object.freeze也不会,用于使工作日名称数组不可变,对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 .我们在这里利用了可变性,但是如果我们真的想要一个不可变的 Date ,并且在当前的 Javascript 中使用强制执行该不变性的语言,我们就必须使用length

Also note that the solutions above don't zero-pad dates before the 10th, unlike the sample output included in the question.另请注意,与问题中包含的示例输出不同,上述解决方案不会将 10 号之前的日期补零。 With ES2017+ that's pretty easy to fix:使用 ES2017+ 很容易修复:

    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.在旧版本的 JS 中执行此操作需要滚动您自己的零填充逻辑,这并不难,但也不是问题的重点。

Alternative with momentjs, working for me替代momentjs,为我工作

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

Below are two nice functional approaches with no external dependency other than Moment:下面是两个不错的函数式方法,除了 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.这将返回一个 Moment 对象数组,然后您可以在其上运行您希望的任何格式方法。

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.为了进一步阅读在 JavaScript 中创建和填充任意长度的数组,还要注意在第一个例子中你必须在映射之前用 null 填充数组,因为在这样做之前它仍然被归类为空,因此 map 函数不会跑。

You could use _.times helper from lodash alongside moment like so:你可以使用_.times助手从lodash旁边那一刻就像这样:

 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('DD-ddd')); // your format monthDate.add(1, 'day'); }); console.log(daysInMonth)
 <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>

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

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.我认为使用方法moment(month).daysInMonth()获取一个月中的天数以及Array.from()生成数组是更清洁和执行的方式。

 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>

To get days in a month with moment.js i use this one :要使用 moment.js 在一个月内获得几天,我使用这个:

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

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.来到这篇文章制作日期选择器(是的...) - 我采用了类似的方法来获得最佳答案,但我认为 for 循环个人更直观/可读。 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.这确实使用基于 JS 0 的日期,所以 5 = 六月,1 = 二月,等等 - 您可以省略日期中的“+1”以表示基于 1 的日期。

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

you can do it using for loop with moment你可以使用 for 循环来实现

 var daysInMonth = []; var monthDate = moment().startOf('month'); for(let i=0;i<monthDate.daysInMonth();i++){ let newDay=monthDate.clone().add(i,'days'); daysInMonth.push(newDay.format('DD-ddd')); } console.log(daysInMonth)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>

This is a little different way to do it but can be used for a list of days in a month:这是一种有点不同的方法,但可以用于一个月中的天数列表:

const getListOfDays = (year, month) => {
  const list = [];
  const date = `${year}-${('0'+month).slice(-2)}`
  const from = moment(date);
  const to = moment(date).add(1, 'months');
  for (let m = moment(from); m.isBefore(to); m.add(1, 'days')) {
   list.push(m.format('YYYY-MM-DD'));
  }
  return list;
};

console.log(getListOfDays(2022,9))

As of moment.js version 2.1.0, when you set a date like:从 moment.js 版本 2.1.0 开始,当您设置如下日期时:

    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.然后你只需要解析日期,你就可以得到一个月的天数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM