Javascript - nhận mảng ngày giữa 2 ngày


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

Tôi muốn "phạm vi" là một mảng các đối tượng ngày, một cho mỗi ngày giữa hai ngày.

Bí quyết là nó cũng nên xử lý ranh giới tháng và năm.

Câu trả lời:


171
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;
}

Dưới đây là bản demo chức năng http://jsfiddle.net/jfhartsock/cM3ZU/


2
Cảm ơn John. Tôi chủ yếu sử dụng của bạn, nhưng bạn có một lỗi byRef, trong đó currentDate không thể bị đẩy vào mảng hoặc bạn sẽ kết thúc với một mảng gồm n phần tử, tất cả là ngày cuối cùng. Thay đổi nó thành currentDate = Ngày mới (currentDate) hoạt động.
Scott Klarenbach

Điều này tốt cho ngày trong tương lai, nhưng khi tôi đang làm việc vào ngày trước như 30 ngày trước thì tôi nên thay đổi mã ở trên để chỉ lấy ngày không phải là thời gian.
vaibhav kulkarni

@vaibhavkulkarni Bạn chỉ cần đảo ngược nguyên mẫu addays () và sửa đổi vòng lặp while. Ngoài ra, các bình luận không phải là nơi để bắt đầu một câu hỏi mới.
John Hartsock

Chúng ta nên loại bỏ thời gian tốt hơn startDateendDate? Bởi vì nếu startDatethời gian muộn hơn stopDatethời gian, nó sẽ không bao gồm stopDatetrong kết quả, phải không?
Hp93

@ Hp93 Không chắc chắn chính xác những gì bạn nói về. Nếu bạn chạy fiddle tôi cung cấp, bạn sẽ thấy rằng nó bao gồm tình huống đó.
John Hartsock

57

Hãy thử điều này, hãy nhớ bao gồm khoảnh khắc 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;
}

Chỉ cần một cải tiến nhỏ: ký hiệu viết tắt để tạo mảng được khuyến nghị var dateArray = [];Chi tiết tại đây
Adrian Moisa

Đây là cách mới để xác định mảng và tôi cho rằng nó ngắn hơn / sạch hơn.
Mohammed Safeer

1
var currentDate = moment(startDate);Khắc phục quan trọng : Trong trường hợp bạn đang sử dụng phương pháp này hai lần vào cùng một thời điểm, bạn sẽ bối rối tại sao nó chỉ hoạt động lần đầu tiên. Điều này xảy ra bởi vì javascripts chuyển các đối tượng bằng tham chiếu để hàm kết thúc bằng cách sử dụng startDate hai lần (tất cả đã bị đột biến). Việc sửa lỗi trên đảm bảo rằng bạn đang chao đảo với các đối tượng js khoảnh khắc mới và duy nhất trong phạm vi chức năng. Kiểm tra câu đố này
Adrian Moisa

51

Tôi đã xem tất cả những người ở trên. Đã kết thúc việc tự viết. Bạn không cần khoảnh khắc cho việc này . Một vòng lặp for là đủ và có ý nghĩa nhất bởi vì vòng lặp for tồn tại để đếm các giá trị trong một phạm vi.

Lót:

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

Phiên bản dài

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

Liệt kê ngày ở giữa:

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"
*/

Ngày từ một ngày qua cho đến bây giờ:

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

Điều gì nếu bạn muốn tìm nạp tất cả các ngày bạn đã chỉ định getDaysArray? Không phải những ngày giữa nó.
Jonjie

cảm ơn! chính xác những gì tôi cần mà không phụ thuộc. :)
mpsyp

2
Hàm này thao tác ngày đầu vào nguồn. :) Tôi đã thử nó.
Hamed Taheri

4
@ HamedTaheri Bạn có, nhưng điều đó có thể được khắc phục bằng cách gán một bản sao bắt đầu cho dt thay vì bắt đầu chính nó, vd for (var arr=[], dt=new Date(start), ...). ;-)
RobG

làm việc tốt, nhưng quá tệ, vòng lặp for (;;) không thể đọc được để bảo trì phần mềm khi bạn làm việc với nhiều người khác.
Victor

27

Tôi sử dụng khoảnh khắc.jsTwix.js, họ cung cấp một sự hỗ trợ rất tuyệt vời cho việc quản lý ngày và thời gian

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

Tôi có cái này chạy trên http://jsfiddle.net/Lkzg1bxb/


Tôi đã tải xuống tất cả các tệp liên quan đến nó nhưng nó vẫn hiển thị lỗi TypeError: khoảnh khắc.twix không phải là một chức năng
vaibhav kulkarni

Bạn có thể phải bao gồm các thư viện. Trong nodejs nó giống như, var khoảnh khắc = Yêu cầu ('khoảnh khắc'); yêu cầu ('twix');
Bác sĩ Bala Soundararaj

18
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)

3
Để an toàn, không giống như những điều trên, bạn thường nên chọn thời gian vào giữa ngày để tránh những thay đổi nhỏ do tiết kiệm ánh sáng ban ngày.
Phrogz

Tôi ước bạn cũng thêm thay đổi giữa ngày cho mã.

15
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;

}

1
Điều này sẽ đóng băng nếu bạn cung cấp ngày theo thứ tự không chính xác
pie6k

11

Nếu bạn đang sử dụng khoảnh khắc thì bạn có thể sử dụng "plugin chính thức" của họ cho các phạm vi moment-rangevà sau đó điều này trở nên tầm thường.

ví dụ nút phạm vi thời điểm:

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

ví dụ trình duyệt phạm vi:

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>

ví dụ ngày fns:

Nếu bạn đang sử dụng date-fnsthì eachDaybạn của bạn và bạn nhận được câu trả lời ngắn gọn và súc tích nhất:

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>


8

Chỉ cần gặp câu hỏi này, cách dễ nhất để làm điều này là sử dụng khoảnh khắc:

Bạn cần cài đặt khoảnh khắc và phạm vi thời gian trước:

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)

6

Tôi đã sử dụng giải pháp @Mohammed Safeer được một thời gian và tôi đã thực hiện một vài cải tiến. Sử dụng ngày hình thành là một thực hành xấu trong khi làm việc trong bộ điều khiển của bạn. moment().format()chỉ nên được sử dụng cho mục đích hiển thị trong chế độ xem. Cũng nên nhớ rằng moment().clone()đảm bảo tách khỏi các tham số đầu vào, nghĩa là ngày đầu vào không bị thay đổi. Tôi đặc biệt khuyến khích bạn sử dụng Moment.js khi làm việc với ngày.

Sử dụng:

  • Cung cấp ngày Moment.js làm giá trị cho startDate, endDatetham số
  • intervaltham số là tùy chọn và mặc định là 'ngày'. Sử dụng các khoảng được sắp xếp theo .add()phương thức (khoảnh khắc.js). Thêm chi tiết tại đây
  • totaltham số này rất hữu ích khi chỉ định các khoảng thời gian tính bằng phút. Nó mặc định là 1.

Gọi:

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

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

Chức năng:

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

6

Sử dụng ES6, bạn có Array.from có ​​nghĩa là bạn có thể viết một hàm thực sự tao nhã, cho phép các Khoảng động (giờ, ngày, tháng).

function getDates(startDate, endDate, interval) {
const duration = endDate - startDate;
const steps = duration / interval;
return Array.from({length: steps+1}, (v,i) => new Date(startDate.valueOf() + (interval * i)));
}
const startDate = new Date(2017,12,30);
const endDate = new Date(2018,1,3);
const dayInterval = 1000 * 60 * 60 * 24; // 1 day
const halfDayInterval = 1000 * 60 * 60 * 12; // 1/2 day

console.log("Days", getDates(startDate, endDate, dayInterval));
console.log("Half Days", getDates(startDate, endDate, halfDayInterval));


2
"Thanh lịch" phụ thuộc vào quan điểm của bạn. new Date(2017,12,30)là ngày 30 tháng 1 năm 2018, đối với tôi, phạm vi ngày bắt đầu vào ngày 29 tháng 1 năm 2018. Không phải tất cả các ngày đều dài 8,64e7 ms (24 giờ) trong đó việc tiết kiệm ánh sáng ban ngày được quan sát. ;-)
RobG

5

Gần đây tôi đã làm việc với Moment.js, sau đây đã thực hiện thủ thuật ..

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

Kết quả sẽ là:

["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"]

3
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"]

1
Vui lòng thêm mô tả và / hoặc thông tin về câu trả lời của bạn và cách giải quyết vấn đề được hỏi để người khác có thể dễ dàng hiểu nó mà không yêu cầu làm rõ
koceeng

Tôi thấy điều này đang bỏ qua 2016-03-31 vì một số lý do!
gỗ92

1
Bạn không nên có vartrước strDatevòng lặp while!
Boris Yakubchik

2

d3js cung cấp rất nhiều chức năng tiện dụng và bao gồm d3.time để thao tác ngày dễ dàng

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

Đối với yêu cầu cụ thể của bạn:

Út

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

hoặc giờ địa phương

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

phạm vi sẽ là một mảng các đối tượng ngày rơi vào giá trị đầu tiên có thể cho mỗi ngày

bạn có thể thay đổi timeDay thành timeHour, timeMonth, vv cho cùng một kết quả vào các khoảng thời gian khác nhau


2

Đây là một lớp lót không yêu cầu bất kỳ thư viện nào trong trường hợp bạn không muốn tạo một chức năng khác. Chỉ cần thay thế startDate (ở hai vị trí) và endDate (là các đối tượng ngày js) bằng các biến hoặc giá trị ngày của bạn. Tất nhiên bạn có thể gói nó trong một chức năng nếu bạn thích

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

điều này không tính đến Ánh sáng ban ngày / Tiết kiệm tiêu chuẩn Thời gian thay đổi .. một số ngày dài hơn và một số ngắn hơn
Mike

2

Tôi sử dụng chức năng này

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

2

Tôi đang sử dụng vòng lặp while đơn giản để tính toán giữa các ngày

var start = new Date("01/05/2017");
var end = new Date("06/30/2017");
var newend = end.setDate(end.getDate()+1);
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);
}


1

Lưu ý: Tôi biết điều này hơi khác so với giải pháp được yêu cầu, nhưng tôi nghĩ nhiều người sẽ thấy nó hữu ích.

Nếu bạn muốn tìm từng khoảng "x" (ngày, tháng, năm, v.v.) giữa hai ngày, khoảnh khắc.js và các gói mở rộng phạm vi thời điểm cho phép chức năng này.

Ví dụ: để tìm mỗi ngày thứ 30 giữa hai ngày :

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

1
  1. Tạo một mảng năm:

    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. Tạo một mảng cho tháng:

            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. Tạo một mảng trong nhiều ngày:

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

1

Bạn có thể làm điều đó một cách dễ dàng bằng khoảnh khắc

Thêm thời điểm cho các phụ thuộc của bạn

npm i moment

Sau đó nhập tệp đó vào tệp của bạn

var moment = require("moment");

Sau đó sử dụng mã sau đây để có được danh sách tất cả các ngày giữa hai ngày

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

0

Điều này có thể giúp ai đó,

Bạn có thể lấy đầu ra hàng từ cái này và định dạng đối tượng row_date như bạn muốn.

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


0

Đây là một phương thức đóng hộp sẽ chấp nhận ngày hoặc chuỗi khoảnh khắc hoặc hỗn hợp làm đầu vào và tạo ra một mảng ngày là ngày khoảnh khắc. Nếu bạn không muốn ngày tháng là đầu ra thì hãy thay đổi map()phương thức trả về.

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

0

@ softvar's Solution, nhưng sau đó bao gồm tùy chọn ngày làm việc

/**
 * 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;
}

0

Chức năng:

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

Sử dụng:

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

Hy vọng nó sẽ giúp bạn

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.