Как получить список дней в месяц с помощью Moment.js
Использование Moment.js Я хотел бы получить все дни в месяце определенного года в массиве. Например:
January-2014:
[
"01-wed",
"02-thr",
"03-fri",
"04-sat"
]
любые предложения? Я просмотрел документы Moment.js, но ничего не нашел. Шкаф, который я получил, был следующим:
moment("2012-02", "YYYY-MM").daysInMonth()
Но это только возвращает int с полными днями для определенного месяца, а не массивом с каждым днем.
Ответы
Ответ 1
Вот функция, которая сделает свое дело (не используя Moment, а просто ванильный 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;
}
Например:
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+ версия:
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;
}
Обратите внимание, что решения, приведенные выше, не ставят нулевые даты до 10 числа, в отличие от примера вывода, включенного в вопрос. С ES2017+ это довольно легко исправить:
result.push('${date.getDate()}'.padStart(2,'0') + '-${names[date.getDay()]}');
Выполнение этого в более старых версиях JS требует применения собственной логики заполнения нулями, что не сложно, но на самом деле не является основным вопросом.
Ответ 2
Альтернатива с импульсами, работающая для меня
function getDaysArrayByMonth() {
var daysInMonth = moment().daysInMonth();
var arrDays = [];
while(daysInMonth) {
var current = moment().date(daysInMonth);
arrDays.push(current);
daysInMonth--;
}
return arrDays;
}
И вы можете проверить
var schedule = getDaysArrayByMonth();
schedule.forEach(function(item) {
console.log(item.format("DD/MM"));
});
Ответ 3
Используя также 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
Ниже приведены два хороших функциональных подхода без внешней зависимости, кроме 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'));
Это возвращает массив объектов Moment, после чего вы можете запустить на нем любой метод форматирования, какой пожелаете.
Для дальнейшего чтения Создание и заполнение массивов произвольной длины в JavaScript также обратите внимание, что в первом примере необходимо заполнить массив нулем, прежде чем отображать его, так как он до сих пор классифицируется как пустой, и поэтому функция карты не будет работать.
Ответ 5
В качестве альтернативы вы можете использовать диапазон моментов для достижения этой цели:
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')));
Ответ 6
Пришёл к этому посту, выбирая дату (да...) - я подошел с похожим подходом к верхнему ответу, но я думаю, что цикл for немного более интуитивно понятен/удобен для чтения. При этом используется дата на основе 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;
}
Ответ 7
Чтобы получить дни в месяце с 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;
}
Затем вызвать функцию
var days = daysInMonth( moment().month() );
Ответ 8
Я думаю, что использование метода 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>
Ответ 9
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');
});
}
Ответ 10
По состоянию на момент .js версии 2.1.0, когда вы устанавливаете дату, например:
moment([2012, 0, 31]).month(1).format("YYYY-MM-DD"); // 2012-02-29
Затем вам просто нужно проанализировать дату, и у вас есть количество дней в месяц.