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

时间:2014-08-31 02:27:10

标签: javascript momentjs

使用Moment.js我希望在一个特定年份的某个月中获得阵列中的所有日子。例如:

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

有什么建议吗?我查看了Moment.js文档但无法找到任何内容。我得到的壁橱是这样的:

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

但是这只返回一个int,其中特定月份的总天数不是每天的数组。

11 个答案:

答案 0 :(得分:37)

这是一个可以解决问题的功能(不使用Moment,只是使用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;
}

例如:

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中执行它需要滚动自己的零填充逻辑,这并不难,但也不是问题的焦点。

答案 1 :(得分:11)

替代momentjs,为我工作

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

答案 2 :(得分:10)

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

答案 3 :(得分:3)

或者,您现在可以使用moment range实现此目的:

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

答案 4 :(得分:3)

以下是两种不错的功能性方法,除了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对象数组,然后可以在其上运行所需的任何格式方法。

为进一步阅读Creating and filling Arrays of arbitrary lengths in JavaScript,还请注意,在第一个示例中,您必须在对数组进行映射之前用null填充数组,因为这样做之前它仍被归类为空,因此map函数将无法运行

答案 5 :(得分:2)

喜欢这篇文章,做一个日期选择器(是的...)-我对最佳答案采用了类似的方法,但是我个人认为for循环更直观/更易读。确实使用了基于JS 0的日期,因此5 = 6月,1 = 2月,依此类推-您可以在日期中省略基于1的日期的“ +1”。

import * as d3 from 'd3';

export class TreeModel {

  rroot: any; // right root
  lroot: any; // left root
  treeLayout: any;
  svg: any;
  N: number = 10;
  treeData: any;

  rect_width: number = 125;
  rect_height: number = 42;

  height: number;
  width: number;
  margin: any = { top: 200, bottom: 90, left: 100, right: 90};
  duration: number= 750;
  nodeWidth: number = 1;
  nodeHeight: number = 1;
  nodeRadius: number = 5;
  horizontalSeparationBetweenNodes: number = 1;
  verticalSeparationBetweenNodes: number = 10;

  selectedNodeByDrag: any;

  selectedNodeByClick: any;
  previousClickedDomNode: any;

  ... omitted for brevity ...

  constructor(){}

  addSvgToContainer(chartContainer: any){
    let element = chartContainer.nativeElement;

    this.width = element.offsetWidth - this.margin.left - this.margin.right;
    this.height = element.offsetHeight - this.margin.top - this.margin.bottom;

    this.svg = d3.select(element).append('svg')
      .attr('width', element.offsetWidth)
      .attr('height', element.offsetHeight)
      .append("g")
      .attr("transform", "translate("
            + this.margin.left + "," + this.margin.top + ")");
    this.svg = this.svg.append("g");

    ... omitted for brevity ...
  }

  // zoom stuff
  ... omitted for brevity ...
  // end zoom stuff

  createLayout(){
    this.treeLayout = d3.tree()
      .size([this.height, this.width])
      .nodeSize([this.nodeWidth + this.horizontalSeparationBetweenNodes, this.nodeHeight + this.verticalSeparationBetweenNodes])
      .separation((a,b)=>{return a.parent == b.parent ? 50 : 200});
  }

  getRandomColor() {
    ... omitted for brevity ...
  }

  chunkify(a, n, balanced) {
    ... omitted for brevity ...
  }

  twoTreeBuildCenterNodesChildren(children:any) {
    // this routine is suppose to build a json/tree object that represent the children of the center node.
    // if there are more than N number of nodes on any level we need to create an additional level to
    // accommodate these nodes.
    ... omitted for brevity ...
  }


  compare(a,b) {
    ... omitted for brevity ...
  }

  buildTwoTreeData(apiJson:any) {
    var componentType = Object.keys(apiJson)[0];
    var centerNodeLeft = {'component_type': componentType, "name": apiJson[componentType].name, "color": "#fff", "children": []};
    var centerNodeRight = {'component_type': componentType, "name": apiJson[componentType].name, "color": "#fff", "children": []};
    var tmp_leftNodes = [];
    for ( var i=0; i < apiJson[componentType].multiparent.length; i++ ) {
      var c = apiJson[componentType].multiparent[i];
      c['color'] = this.getRandomColor();
      c['name'] = c.parent.name;
      tmp_leftNodes.push(c);
    }
    var leftNodes = tmp_leftNodes.sort(this.compare);
    var rightNodes = apiJson[componentType].children.sort(this.compare);
    var right_center_node_children = this.twoTreeBuildCenterNodesChildren(rightNodes.sort(this.compare));
    var left_center_node_children = this.twoTreeBuildCenterNodesChildren(leftNodes.sort(this.compare));
    centerNodeLeft.children = left_center_node_children;
    centerNodeRight.children = right_center_node_children;
    return[centerNodeLeft, centerNodeRight];

  }

  translateJson(apiJson:any){ return this.buildTwoTreeData(apiJson); }

  createTreeData(rawData: any){
    var parsedData = this.translateJson(rawData);
    this.lroot = d3.hierarchy(parsedData[0]);
    this.lroot.x0 = this.height / 2;
    this.lroot.y0 = 0;
    this.lroot.children.map((d)=>this.collapse(d));
    this.rroot = d3.hierarchy(parsedData[1]);
    this.rroot.x0 = this.height / 2;
    this.rroot.y0 = 0;
    this.rroot.children.map((d)=>this.collapse(d));
  }

  collapse(d) {
    if(d.children) {
      d._children = d.children
      d._children.map((d)=>this.collapse(d));
      d.children = null
    }
  }

  expand_node(d) {
    if (d.children) { d._children = d.children; d.children = null; } else { d.children = d._children; d._children = null; }
  }

  expand(d) {
    if(d._children) {
      d.children = d._children
      d.children.map((d)=>this.expand(d));
      d.children = null
    }
  }

  rightTreeUpdate(source) {
    const treeData = this.treeLayout(this.rroot);
    this.setNodes(source, treeData, 'right');
    this.setLinks(source, treeData, 'right');
  }

  leftTreeUpdate(source) {
    const treeData = this.treeLayout(this.lroot);
    this.setNodes(source, treeData, 'left');
    this.setLinks(source, treeData, 'left');
  }

  setNodes(source:any, treeData: any, side: string){
    let nodes = treeData.descendants();
    let treeModel= this;
    if ( side === 'left') {
      let width = this.width;
      nodes.forEach(function (d) { d.y = (d.depth * -180) });
    } else {
      // this draws everything to the right.
      nodes.forEach(function(d){ d.y = d.depth * 180});
    }

    var node = this.svg.selectAll('g.node')
        .data(nodes, function(d) { return d.id || (d.id = ++this.i); });
    var nodeEnter = node.enter().append('g')
        .attr('class', 'node')
        .attr("transform", function(d) {
            return "   translate(" + source.y0 + "," + source.x0 + ")";
        });

    nodeEnter.append('rect')
      .attr('class', 'node-rect')
      .attr('x', 0)
      .attr('y', 0)
      .attr('rx', 6)
      .attr('ry', 6)
      .attr('width', this.rect_width)
      .attr('height', this.rect_height)
      .attr('stroke', 'black')
      .style("fill", function(d) {
        return d.data.color;
      });

    nodeEnter.append('text')
      .attr('y', 20)
      .attr('x', 40)
      .attr("text-anchor", "middle")
      .text(function(d){
          return (d.data.name || d.data.description || d.id);
      });

    var nodeUpdate = nodeEnter.merge(node);
    nodeUpdate.transition()
      .duration(this.duration)
      .attr("transform", function(d) {
        return "translate(" + d.y + "," + d.x  + ")";
       });

    var nodeExit = node.exit().transition()
        .duration(this.duration)
        .attr("transform", function(d) {
            return "translate(" + source.y + "," + source.x + ")";
        })
        .remove();

    // On exit reduce the node circles size to 0
    nodeExit.select('circle')
      .attr('r', 1e-6);

    // Store the old positions for transition.
    nodes.forEach(function(d){
      d.x0 = d.x;
      d.y0 = d.y;
    });
    // On exit reduce the opacity of text labels
    nodeExit.select('text')
      .style('fill-opacity', 1e-6);

    nodeEnter
      .on('click', function(d){
        treeModel.click(d, this);
        //treeModel.update(d);
        // treeModel.rightTreeUpdate(d);
      });
  }

    ... omitted for brevity ...

  setLinks( source: any, treeData: any, side: string){
    let links = treeData.descendants().slice(1);
    var link = this.svg.selectAll('path.link')
      .data(links, function(d) { return d.id; });

    // Enter any new links at the parent's previous position.
    var linkEnter = link.enter().insert('path', "g")
      .attr("class", "link")
      .attr('fill', 'none')
      .attr('stroke', 'black')
      .attr('d', (d)=>{
        var o = {x: source.x0, y: source.y0}
        return this.rdiagonalCurvedPath(o, o)
      });

    var linkUpdate = linkEnter.merge(link);

    linkUpdate.transition()
      .duration(this.duration)
      .attr('d', (d)=>{return this.rdiagonalCurvedPath(d, d.parent)});

    var linkExit = link.exit().transition()
      .duration(this.duration)
      .attr('d', (d) => {
        var o = {x: source.x, y: source.y}
        return this.rdiagonalCurvedPath(o, o)
      })
      .remove();
  }

  click(d, domNode) {
    if( d._children ) {
      this.expand_node(d);
    } else if ( d.children) {
      this.collapse(d);
    } else {
      console.log('click() skipping load of new data for now ');
    }
    // HERE IS WHERE I CALL
    // rightTreeUpdate() after leftTreeUpdate() which displays the right tree, but not the left tree.
    this.leftTreeUpdate(this.lroot);
    this.rightTreeUpdate(this.rroot);
  }

    ... omitted for brevity ...
}

答案 6 :(得分:1)

我认为使用方法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>

答案 7 :(得分:0)

要使用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 :(得分:0)

body {
  text-align: center;
}

.navbar {
  /* overflow: hidden; */
  background-color: #333;
  width: 100%;
  position: none;
  height: 60px;
}

.navbar a {
  font-size: 22px;
  color: #fff;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  display: inline;
  position: none;
}

.navbar a:hover,
.dropdown:hover .dropbtn {
  color: pink;
}

.dropdown {
  display: inline;
  overflow: hidden;
  position: relative;
}

.dropdown .dropbtn {
  font-size: 22px;
  cursor: pointer;
  color: white;
  padding: 14px 16px;
  background-color: inherit;
  font-family: inherit;
  margin: 0;
  text-align: center;
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f9f9f9;
  min-width: 120px;
  box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
  z-index: 1;
  top: 40px;
  right: 0;
  left: 0;
}

.dropdown-content a {
  float: none;
  color: black;
  padding: 12px 16px;
  text-decoration: none;
  display: block;
  text-align: left;
}

.dropdown-content a:hover {
  background-color: #ddd;
}

.dropdown:hover .dropdown-content {
  display: block;
}

答案 9 :(得分:0)

您可以使用带有瞬间的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>

答案 10 :(得分:-3)

从moment.js版本2.1.0开始,当您设置日期时:

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

然后你只需要解析日期,你就有一个月的天数。