Javascript - 获取2个日期之间的日期数组

时间:2010-12-10 21:46:19

标签: javascript node.js date datetime date-range

var range = getDates(new Date(), new Date().addDays(7));

我希望“range”是一个日期对象数组,每个日期之间有一个日期对象。

诀窍在于它应该处理月份和年份的界限。

29 个答案:

答案 0 :(得分:149)

Date.prototype.addDays = function(days) {
    var date = new Date(this.valueOf());
    date.setDate(date.getDate() + days);
    return date;
}

function getDates(startDate, stopDate) {
    var dateArray = new Array();
    var currentDate = startDate;
    while (currentDate <= stopDate) {
        dateArray.push(new Date (currentDate));
        currentDate = currentDate.addDays(1);
    }
    return dateArray;
}

这是一个功能demo http://jsfiddle.net/jfhartsock/cM3ZU/

答案 1 :(得分:37)

试试这个,记得包括片刻js,

function getDates(startDate, stopDate) {
    var dateArray = [];
    var currentDate = moment(startDate);
    var stopDate = moment(stopDate);
    while (currentDate <= stopDate) {
        dateArray.push( moment(currentDate).format('YYYY-MM-DD') )
        currentDate = moment(currentDate).add(1, 'days');
    }
    return dateArray;
}

答案 2 :(得分:25)

我使用moment.jsTwix.js他们为日期和时间操作提供了非常好的支持

var itr = moment.twix(new Date('2012-01-15'),new Date('2012-01-20')).iterate("days");
var range=[];
while(itr.hasNext()){
    range.push(itr.next().toDate())
}
console.log(range);

我在http://jsfiddle.net/Lkzg1bxb/

上运行此功能

答案 3 :(得分:12)

我查看了上面的所有内容。结束写自己。 你不需要这个的时刻。 原生for循环足够并且最有意义,因为for循环存在以计算范围内的值。

一个班轮:

var getDaysArray = function(s,e) {for(var a=[],d=s;d<=e;d.setDate(d.getDate()+1)){ a.push(new Date(d));}return a;};

长版

var getDaysArray = function(start, end) {
    for(var arr=[],dt=start; dt<=end; dt.setDate(dt.getDate()+1)){
        arr.push(new Date(dt));
    }
    return arr;
};

列出日期:

var daylist = getDaysArray(new Date("2018-05-01"),new Date("2018-07-01"));
daylist.map((v)=>v.toISOString().slice(0,10)).join("")
/*
Output: 
    "2018-05-01
    2018-05-02
    2018-05-03
    ...
    2018-06-30
    2018-07-01"
*/

从过去的日期到现在的天数:

var daylist = getDaysArray(new Date("2018-05-01"),new Date());
daylist.map((v)=>v.toISOString().slice(0,10)).join("")

答案 4 :(得分:12)

var boxingDay = new Date("12/26/2010");
var nextWeek  = boxingDay*1 + 7*24*3600*1000;

function getDates( d1, d2 ){
  var oneDay = 24*3600*1000;
  for (var d=[],ms=d1*1,last=d2*1;ms<last;ms+=oneDay){
    d.push( new Date(ms) );
  }
  return d;
}

getDates( boxingDay, nextWeek ).join("\n");
// Sun Dec 26 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Mon Dec 27 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Tue Dec 28 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Wed Dec 29 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Thu Dec 30 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Fri Dec 31 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Sat Jan 01 2011 00:00:00 GMT-0700 (Mountain Standard Time)

答案 5 :(得分:12)

function (startDate, endDate, addFn, interval) {

 addFn = addFn || Date.prototype.addDays;
 interval = interval || 1;

 var retVal = [];
 var current = new Date(startDate);

 while (current <= endDate) {
  retVal.push(new Date(current));
  current = addFn.call(current, interval);
 }

 return retVal;

}

答案 6 :(得分:7)

刚刚遇到这个问题,最简单的方法就是利用时刻:

您需要先安装时刻和时刻范围:

const Moment = require('moment');
const MomentRange = require('moment-range');
const moment = MomentRange.extendMoment(Moment);

const start = moment()
const end = moment().add(2, 'months')
const range = moment.range(start, end)
const arrayOfDates = Array.from(range.by('days'))
console.log(arrayOfDates)

答案 7 :(得分:6)

我一直在使用@Mohammed Safeer解决方案,我做了一些改进。在控制器中工作时,使用格式化日期是一种不好的做法。 moment().format()应仅用于视图中的显示目的。还要记住moment().clone()确保与输入参数分离,这意味着输入日期不会改变。我强烈建议您在使用日期时使用moment.js。

用法:

  • 提供moment.js日期作为startDateendDate参数
  • 的值
  • interval参数是可选的,默认为“days”。使用由.add()方法(moment.js)支持的间隔。 More details here
  • 指定以分钟为单位的间隔时,
  • total参数非常有用。默认为1。

调用:

var startDate = moment(),
    endDate = moment().add(1, 'days');

getDatesRangeArray(startDate, endDate, 'minutes', 30);

功能:

var getDatesRangeArray = function (startDate, endDate, interval, total) {
    var config = {
            interval: interval || 'days',
            total: total || 1
        },
        dateArray = [],
        currentDate = startDate.clone();

    while (currentDate < endDate) {
        dateArray.push(currentDate);
        currentDate = currentDate.clone().add(config.total, config.interval);
    }

    return dateArray;
};

答案 8 :(得分:5)

如果您使用的是时刻,则可以将其“官方插件”用于范围moment-range,然后变得微不足道了。

力矩范围节点示例:

const Moment = require('moment');
const MomentRange = require('moment-range');
const moment = MomentRange.extendMoment(Moment);

const start = new Date("11/30/2018"), end = new Date("09/30/2019")
const range = moment.range(moment(start), moment(end));

console.log(Array.from(range.by('day')))

瞬间范围浏览器示例:

window['moment-range'].extendMoment(moment);

const start = new Date("11/30/2018"), end = new Date("09/30/2019")
const range = moment.range(moment(start), moment(end));

console.log(Array.from(range.by('day')))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-range/4.0.1/moment-range.js"></script>

日期信息示例:

如果您使用的是date-fns,那么eachDay是您的朋友,那么您将获得最短,最简洁的答案:

console.log(dateFns.eachDay(
  new Date(2018, 11, 30),
  new Date(2019, 30, 09)
))
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.29.0/date_fns.min.js"></script>

答案 9 :(得分:4)

我最近和moment.js一起工作,跟着做了诀窍..

function getDateRange(startDate, endDate, dateFormat) {
        var dates = [],
            end = moment(endDate),
            diff = endDate.diff(startDate, 'days');

        if(!startDate.isValid() || !endDate.isValid() || diff <= 0) {
            return;
        }

        for(var i = 0; i < diff; i++) {
            dates.push(end.subtract(1,'d').format(dateFormat));
        }

        return dates;
    };
    console.log(getDateRange(startDate, endDate, dateFormat));

结果将是:

["09/03/2015", "10/03/2015", "11/03/2015", "12/03/2015", "13/03/2015", "14/03/2015", "15/03/2015", "16/03/2015", "17/03/2015", "18/03/2015"]

答案 10 :(得分:3)

这是一个不需要任何库的单行内容,以防你不想创建另一个函数。只需用你的变量或日期值替换startDate(在两个地方)和endDate(它们是js日期对象)。当然,如果您愿意,可以将它包装在一个函数中

Array(Math.floor((endDate - startDate) / 86400000) + 1).fill().map((_, idx) => (new Date(startDate.getTime() + idx * 86400000)))

答案 11 :(得分:3)

使用ES6你有Array.from意味着你可以编写一个非常优雅的功能,它允许动态间隔(小时,天,月)。

 public async void OnSearch_Location(object o, EventArgs args)
    {
        if (location.Text == string.Empty || location.Text == null)
        {
        await Navigation.PushAsync(new ListValuePage("Location", filePath, 
     pos, list));
       }
        else
        {
            for (int p = 0; p < list.Count; p++)
            {
                if (list.ElementAt(p).Aisle + "." + list.ElementAt(p).Bin + 
    "." + list.ElementAt(p).Level == location.Text)
                {
                    line.Text = 
     Convert.ToString(list.ElementAt(p).Line_Number);
                    location.Text = list.ElementAt(p).Aisle + "." + 
    list.ElementAt(p).Bin + "." + list.ElementAt(p).Level;
                   item.Text = list.ElementAt(p).Item_Number;
                    name.Text = list.ElementAt(p).Name;
                   if (list.ElementAt(p).Order_Qty == 0)
                    {
                        order_uom.Text = "";
                    }
                    else
                    {
                        order_qty.Text = 
   Convert.ToString(list.ElementAt(p).Order_Qty);
                    }

                    order_uom.Text = list.ElementAt(p).Order_UOM;
                    if (list.ElementAt(p).Consumption_UOM == string.Empty || 
    list.ElementAt(p).Consumption_UOM == null)
                    {
                       consume_lbl.IsVisible = false;
                        consume_qty.IsVisible = false;
                        consume_uom.IsVisible = false;
                    }
                    else
                    {
                        consume_lbl.IsVisible = true;
                        consume_qty.IsVisible = true;
                        consume_uom.IsVisible = true;
                        if (list.ElementAt(p).Consumption_Qty == 0)
                        {
                            consume_qty.Text = "";
                        }
                        else
                        {
                            consume_qty.Text = 
     Convert.ToString(list.ElementAt(p).Consumption_Qty);
                        }

                       consume_uom.Text = list.ElementAt(p).Consumption_UOM;
       }
       }
            }
        }

    }

答案 12 :(得分:3)

您可以使用momentJS轻松完成

为您的依赖添加时刻

npm i moment

然后将其导入您的文件中

var moment = require("moment");

然后使用以下代码获取两个日期之间所有日期的列表

let dates = [];
let currDate = moment.utc(new Date("06/30/2019")).startOf("day");
let lastDate = moment.utc(new Date("07/30/2019")).startOf("day");

do {
 dates.push(currDate.clone().toDate());
} while (currDate.add(1, "days").diff(lastDate) < 0);
dates.push(currDate.clone().toDate());

console.log(dates);

答案 13 :(得分:2)

我在使用以上答案时遇到了麻烦。由于本地夏令时(DST)引起的时区偏移,因此日期范围缺少单日。我使用UTC日期实现了一个可解决该问题的版本:

function dateRange(startDate, endDate, steps = 1) {
  const dateArray = [];
  let currentDate = new Date(startDate);

  while (currentDate <= new Date(endDate)) {
    dateArray.push(new Date(currentDate));
    // Use UTC date to prevent problems with time zones and DST
    currentDate.setUTCDate(currentDate.getUTCDate() + steps);
  }

  return dateArray;
}

const dates = dateRange('2020-09-27', '2020-10-28');
console.log(dates);

注意:是应用特定时区还是DST,完全取决于您的locale。覆盖这通常不是一个好主意。使用UTC dates可以缓解大多数与时间相关的问题。

奖金:您可以使用可选的steps参数设置要为其创建时间戳记的时间间隔。如果要每周时间戳记,请将steps设置为7

答案 14 :(得分:2)

var listDate = [];
var startDate ='2017-02-01';
var endDate = '2017-02-10';
var dateMove = new Date(startDate);
var strDate = startDate;

while (strDate < endDate){
  var strDate = dateMove.toISOString().slice(0,10);
  listDate.push(strDate);
  dateMove.setDate(dateMove.getDate()+1);
};
console.log(listDate);

//["2017-02-01", "2017-02-02", "2017-02-03", "2017-02-04", "2017-02-05", "2017-02-06", "2017-02-07", "2017-02-08", "2017-02-09", "2017-02-10"]

答案 15 :(得分:2)

d3js提供了许多方便的功能,并包含d3.time以便于日期操作

https://github.com/d3/d3-time

根据您的具体要求:

UTC

var range = d3.utcDay.range(new Date(), d3.utcDay.offset(new Date(), 7));

或当地时间

var range = d3.timeDay.range(new Date(), d3.timeDay.offset(new Date(), 7));

范围将是一个日期对象数组,它们落在每天的第一个可能值

您可以将timeDay更改为timeHour,timeMonth等,以便在不同的时间间隔内获得相同的结果

答案 16 :(得分:1)

注意:我知道这与请求的解决方案略有不同,但是我认为许多人会发现它很有用。

如果要查找两个日期之间的每个“ x”间隔(天,月,年等),请使用moment.jsmoment-range扩展软件包以启用此功能。

例如,查找两个日期之间的第30天

window['moment-range'].extendMoment(moment);

var dateString = "2018-05-12 17:32:34.874-08";
var start  = new Date(dateString);
var end    = new Date();
var range1 = moment.range(start, end);
var arrayOfIntervalDates = Array.from(range1.by('day', { step: 30 }));

arrayOfIntervalDates.map(function(intervalDate){
  console.log(intervalDate.format('YY-M-DD'))
});

答案 17 :(得分:1)

这就是我喜欢的方式

// hours * minutes * seconds * milliseconds
const DAY_IN_MS = 24 * 60 * 60 * 1000

/**
 * Get range of dates 
 * @param {Date} startDate 
 * @param {Number} numOfDays 
 * @returns {array}
 */
const dateRange = (startDate, numOfDays) => {
    const startDateMs = startDate.getTime()

    // get array of days and map it to Date object
    return [...Array(numOfDays).keys()].map(i => new Date(startDateMs + i * DAY_IN_MS))
}

答案 18 :(得分:1)

  1. 生成一系列年份:

    const DAYS = () => {
     const days = []
     const dateStart = moment()
     const dateEnd = moment().add(30, ‘days')
     while (dateEnd.diff(dateStart, ‘days') >= 0) {
      days.push(dateStart.format(‘D'))
      dateStart.add(1, ‘days')
     }
     return days
    }
    console.log(DAYS())
    
  2. 生成月份数组:

            const MONTHS = () => {
             const months = []
             const dateStart = moment()
             const dateEnd = moment().add(12, ‘month')
             while (dateEnd.diff(dateStart, ‘months') >= 0) {
              months.push(dateStart.format(‘M'))
              dateStart.add(1, ‘month')
             }
             return months
            }
            console.log(MONTHS())
    
  3. 几天生成一个数组:

            const DAYS = () => {
             const days = []
             const dateStart = moment()
             const dateEnd = moment().add(30, ‘days')
             while (dateEnd.diff(dateStart, ‘days') >= 0) {
              days.push(dateStart.format(‘D'))
              dateStart.add(1, ‘days')
             }
             return days
            }
            console.log(DAYS())
    

答案 19 :(得分:1)

我使用简单的while循环计算日期之间

&#13;
&#13;
var start = new Date("01/05/2017");
var end = new Date("06/30/2017");
var newend = end.setDate(end.getDate()+1);
var end = new Date(newend);
while(start < end){
   console.log(new Date(start).getTime() / 1000); // unix timestamp format
   console.log(start); // ISO Date format          
   var newDate = start.setDate(start.getDate() + 1);
   start = new Date(newDate);
}
&#13;
&#13;
&#13;

答案 20 :(得分:0)

功能:

  var dates = [],
      currentDate = startDate,
      addDays = function(days) {
        var date = new Date(this.valueOf());
        date.setDate(date.getDate() + days);
        return date;
      };
  while (currentDate <= endDate) {
    dates.push(currentDate);
    currentDate = addDays.call(currentDate, 1);
  }
  return dates;
};

用法:

var dates = getDatesRange(new Date(2019,01,01), new Date(2019,01,25));                                                                                                           
dates.forEach(function(date) {
  console.log(date);
});

希望它对您有帮助

答案 21 :(得分:0)

我使用此功能

function getDatesRange(startDate, stopDate) {
    const ONE_DAY = 24*3600*1000;
    var days= [];
    var currentDate = new Date(startDate);
    while (currentDate <= stopDate) {
        days.push(new Date (currentDate));
        currentDate = currentDate - 1 + 1 + ONE_DAY;
    }
    return days;
}

答案 22 :(得分:0)

@softvar的解决方案,但其中包括工作日期选项

/**
 * Returns array of working days between two dates.
 *
 * @param {string} startDate
 *   The start date in yyyy-mm-dd format.
 * @param {string} endDate
 *   The end date in yyyy-mm-dd format.
 * @param {boolean} onlyWorkingDays
 *   If true only working days are returned. Default: false
 *
 * @return {array}
 *   Array of dates in yyyy-mm-dd string format.
 */
function getDates(startDate, stopDate, onlyWorkingDays) {
  let doWd = typeof onlyWorkingDays ==='undefined' ? false : onlyWorkingDays;

  let dateArray = [];  
  let dayNr;
  let runDateObj = moment(startDate);  
  let stopDateObj = moment(stopDate);

  while (runDateObj <= stopDateObj) {
    dayNr = runDateObj.day();
    if (!doWd || (dayNr>0 && dayNr<6)) {
     dateArray.push(moment(runDateObj).format('YYYY-MM-DD'));  
    }

    runDateObj = moment(runDateObj).add(1, 'days');
  }
  return dateArray;
}

答案 23 :(得分:0)

这是一种固定方法,可以接受Moment日期或字符串或混合物作为输入,并生成日期数组作为Moment日期。如果您不希望将即时日期作为输出,请更改map()方法返回的内容。

const moment = require('moment');

// ...

/**
 * @param {string|import('moment').Moment} start
 * @param {string|import('moment').Moment} end
 * @returns {import('moment').Moment[]}
 */
const getDateRange = (start, end) => {
  const s = moment.isMoment(start) ? start : moment(start);
  const e = moment.isMoment(end) ? end : moment(end);
  return [...Array(1 + e.diff(s, 'days')).keys()].map(n => moment(s).add(n, 'days'));
};

答案 24 :(得分:0)

这可能对某人有帮助,

  

您可以从中获取行输出并根据需要格式化row_date对象。

var from_date = '2016-01-01';
var to_date = '2016-02-20';

var dates = getDates(from_date, to_date);

console.log(dates);

function getDates(from_date, to_date) {
  var current_date = new Date(from_date);
  var end_date     = new Date(to_date);

  var getTimeDiff = Math.abs(current_date.getTime() - end_date.getTime());
  var date_range = Math.ceil(getTimeDiff / (1000 * 3600 * 24)) + 1 ;

  var weekday = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"];
  var months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
  var dates = new Array();

  for (var i = 0; i <= date_range; i++) {
     var getDate, getMonth = '';

     if(current_date.getDate() < 10) { getDate = ('0'+ current_date.getDate());}
     else{getDate = current_date.getDate();}

    if(current_date.getMonth() < 9) { getMonth = ('0'+ (current_date.getMonth()+1));}
    else{getMonth = current_date.getMonth();}

    var row_date = {day: getDate, month: getMonth, year: current_date.getFullYear()};
    var fmt_date = {weekDay: weekday[current_date.getDay()], date: getDate, month: months[current_date.getMonth()]};
    var is_weekend = false;
    if (current_date.getDay() == 0 || current_date.getDay() == 6) {
        is_weekend = true;
    }
    dates.push({row_date: row_date, fmt_date: fmt_date, is_weekend: is_weekend});
    current_date.setDate(current_date.getDate() + 1);
 }
 return dates;
}

https://gist.github.com/pranid/3c78f36253cbbc6a41a859c5d718f362.js

答案 25 :(得分:0)

使用 lodash 和 moment:

const startDate = moment();
_.range(0, 7).map((d) => startDate.clone().add(d, 'day').toDate())

答案 26 :(得分:0)

这是使用 date-fns 库的另外几行解决方案:

const { format, differenceInDays, addDays } = dateFns;

const getRangeDates = (startDate, endDate) => {
  const days = differenceInDays(endDate, startDate);
  console.log([...Array(days + 1).keys()].map((i) => format(addDays(startDate, i), 'YYYY-MM-DD')));
};

getRangeDates('2021-06-01', '2021-06-05');
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.30.1/date_fns.js"></script>

答案 27 :(得分:0)

getDates = (from, to) => {
    const cFrom = new Date(from);
    const cTo = new Date(to);

    let daysArr = [new Date(cFrom)];
    let tempDate = cFrom;

    while (tempDate < cTo) {
        tempDate.setUTCDate(tempDate.getUTCDate() + 1);
        daysArr.push(new Date(tempDate));
    }

    return daysArr;
}

答案 28 :(得分:-1)

Array(7).fill().map((_,i) => dayjs().subtract(i, "day").format("YYYY-MM-DD"));