Javascript - dapatkan berbagai tanggal antara 2 tanggal


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

Saya ingin "rentang" menjadi array objek tanggal, satu untuk setiap hari antara dua tanggal.

Kuncinya adalah bahwa ia harus menangani batas bulan dan tahun juga.

Jawaban:


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

Berikut ini adalah demo fungsional http://jsfiddle.net/jfhartsock/cM3ZU/


2
John terima kasih. Saya kebanyakan menggunakan milik Anda, tetapi Anda memiliki bug byRef, pada saat ini tanggal tidak bisa didorong ke array atau Anda akan berakhir dengan array n elemen, semua sebagai tanggal terakhir. Mengubahnya ke currentDate = new Date (currentDate) berfungsi.
Scott Klarenbach

ini bagus untuk tanggal mendatang, tetapi ketika saya bekerja pada tanggal yang lalu seperti 30 hari sebelumnya di mana saya harus mengubah kode di atas untuk mendapatkan hanya tanggal bukan waktu.
vaibhav kulkarni

@vaibhavkulkarni Anda dapat membalikkan prototipe addays () dan memodifikasi loop while. Selain itu, komentar bukanlah tempat untuk memulai pertanyaan baru.
John Hartsock

Haruskah kita lebih baik menghapus waktu dari startDatedan endDate? Karena jika startDatewaktu lebih lama dari stopDatewaktu, itu tidak akan termasuk stopDatedalam hasilnya, kan?
Hp93

@ Hp93 Tidak yakin persis apa yang Anda bicarakan. Jika Anda menjalankan biola saya berikan Anda akan melihat bahwa itu mencakup situasi itu.
John Hartsock

58

Coba ini, ingatlah untuk memasukkan momen 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;
}

Hanya perbaikan kecil: notasi steno untuk membuat array disarankan var dateArray = [];Detail di sini
Adrian Moisa

Ini adalah cara baru untuk mendefinisikan array, dan saya kira itu lebih pendek / lebih bersih.
Mohammed Safeer

1
Perbaikan penting : var currentDate = moment(startDate);Jika Anda menggunakan metode ini dua kali pada saat yang sama. Tanggal Anda akan bingung mengapa itu hanya bekerja pertama kali. Ini terjadi karena javascripts meneruskan objek dengan referensi sehingga fungsi berakhir menggunakan startDate dua kali (yang sudah dimutasi). Menambal perbaikan di atas memastikan bahwa Anda sedang mengelus dengan objek js momen baru dan unik dalam lingkup fungsi. Lihat biola
Adrian Moisa

53

Saya melihat semua yang di atas. Akhirnya menulis sendiri. Anda tidak perlu momen untuk ini . Asli untuk loop sudah cukup dan paling masuk akal karena untuk loop ada untuk menghitung nilai dalam rentang.

Satu Liner:

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

Versi Panjang

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

Daftar tanggal di antara:

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

Hari dari tanggal yang lalu hingga sekarang:

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

Bagaimana jika Anda ingin mengambil semua hari yang Anda tentukan getDaysArray? Bukan hari-hari di antara itu.
Jonjie

Terima kasih! persis apa yang saya butuhkan tanpa ketergantungan. :)
mpsyp

2
fungsi ini memanipulasi tanggal input sumber. :) Saya mengujinya.
Hamed Taheri

4
@ HamedTaheri — ya, tapi itu bisa diperbaiki dengan menetapkan salinan mulai ke dt daripada memulai sendiri, misalnya for (var arr=[], dt=new Date(start), ...). ;-)
RobG

bekerja dengan baik, tetapi loop yang terlalu buruk untuk (;;) tidak dapat dibaca oleh pemeliharaan perangkat lunak ketika Anda bekerja dengan banyak orang lain.
Victor

27

Saya menggunakan moment.js dan Twix.js mereka memberikan dukungan yang sangat bagus untuk pembuatan tanggal dan waktu

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

Saya menjalankan ini di http://jsfiddle.net/Lkzg1bxb/


Saya telah mengunduh semua file yang terkait dengannya tetapi masih menunjukkan kesalahan TypeError: moment.twix bukan fungsi
vaibhav kulkarni

Anda mungkin harus memasukkan perpustakaan. Dalam nodejs seperti, var moment = require ('moment'); membutuhkan ('twix');
Dr 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
Agar aman, tidak seperti di atas, Anda biasanya harus memilih waktu di tengah hari untuk menghindari sedikit variasi karena penghematan siang hari.
Phrogz

Saya berharap Anda juga menambahkan perubahan tengah hari ke kode juga.
ayam

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
Ini akan membeku jika Anda memberikan tanggal dalam urutan yang salah
pie6k

11

Jika Anda menggunakan momen maka Anda dapat menggunakan "plugin resmi" mereka untuk rentang moment-rangedan kemudian ini menjadi sepele.

contoh simpul rentang-momen:

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

contoh browser rentang-momen:

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>

contoh tanggal fns:

Jika Anda menggunakan date-fnsmaka itu eachDayadalah teman Anda dan Anda mendapatkan jawaban tersingkat dan paling singkat:

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

Baru saja menemukan pertanyaan ini, cara termudah untuk melakukannya adalah menggunakan momen:

Anda harus menginstal momen dan rentang-waktu terlebih dahulu:

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

Saya telah menggunakan solusi @Mohammed Safeer untuk sementara waktu dan saya membuat beberapa perbaikan. Menggunakan tanggal yang diformat adalah praktik yang buruk saat bekerja di pengontrol Anda. moment().format()harus digunakan hanya untuk tujuan tampilan dalam tampilan. Ingat juga itumoment().clone() memastikan pemisahan dari parameter input, yang berarti bahwa tanggal input tidak diubah. Saya sangat menyarankan Anda untuk menggunakan moment.js saat bekerja dengan kencan.

Pemakaian:

  • Berikan tanggal moment.js sebagai nilai untuk startDate, endDateparameter
  • intervalparameter bersifat opsional dan standarnya adalah 'hari'. Gunakan interval yang didukung oleh .add()metode (moment.js). Lebih detail di sini
  • totalparameter berguna ketika menentukan interval dalam menit. Standarnya adalah 1.

Memohon:

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

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

Fungsi:

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

Menggunakan ES6 Anda memiliki Array. Dari artinya Anda dapat menulis fungsi yang sangat elegan, yang memungkinkan untuk Interval dinamis (jam, hari, bulan).

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
"Elegan" tergantung pada sudut pandang Anda. new Date(2017,12,30)adalah 30 Januari 2018, bagi saya rentang tanggal dimulai pada 29 Januari 2018. Tidak semua hari panjangnya 8.64e7 ms (24 jam) di mana penghematan cahaya matahari diamati. ;-)
RobG

5

Saya baru-baru ini bekerja dengan moment.js, mengikuti melakukan trik ..

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

Hasilnya adalah:

["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
Silakan tambahkan lebih banyak deskripsi dan / atau informasi tentang jawaban Anda dan bagaimana memecahkan masalah yang ditanyakan sehingga orang lain dapat dengan mudah memahaminya tanpa meminta klarifikasi
koceeng

Saya menemukan ini melewatkan 2016-03-31 untuk beberapa alasan!
woodhead92

1
Anda seharusnya tidak memiliki varsebelumnya strDatedi dalam loop sementara!
Boris Yakubchik

2

d3js menyediakan banyak fungsi praktis dan termasuk d3.time untuk manipulasi tanggal yang mudah

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

Untuk permintaan spesifik Anda:

UTC

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

atau waktu setempat

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

range akan berupa array objek tanggal yang jatuh pada nilai pertama yang mungkin untuk setiap hari

Anda dapat mengubah timeDay ke timeHour, timeMonth dll untuk hasil yang sama pada interval yang berbeda


2

Berikut adalah satu liner yang tidak memerlukan pustaka jika Anda tidak ingin membuat fungsi lain. Cukup ganti startDate (di dua tempat) dan endDate (yang merupakan objek tanggal js) dengan variabel atau nilai tanggal Anda. Tentu saja Anda bisa membungkusnya dalam suatu fungsi jika Anda mau

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

ini tidak mempertimbangkan perubahan Siang Hari / Waktu Tabungan Standar .. beberapa hari lebih panjang dan beberapa lebih pendek
Mike

2

Saya menggunakan fungsi ini

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

Saya menggunakan loop sementara sederhana untuk menghitung antara tanggal

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

catatan: Saya sadar ini sedikit berbeda dari solusi yang diminta, tetapi saya rasa banyak yang akan merasakan manfaatnya.

Jika Anda ingin menemukan setiap interval "x" (hari, bulan, tahun, dll ...) antara dua tanggal, moment.js dan rentang momen paket ekstensi memungkinkan fungsi ini.

Misalnya, untuk menemukan setiap hari ke 30 antara dua tanggal :

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. Hasilkan array tahun:

    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. Buat array untuk bulan:

            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. Buat array selama berhari-hari:

            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

Anda dapat melakukannya dengan mudah menggunakan momentJS

Tambahkan momen ke dependensi Anda

npm i moment

Kemudian impor itu di file Anda

var moment = require("moment");

Kemudian gunakan kode berikut untuk mendapatkan daftar semua tanggal antara dua tanggal

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

Ini dapat membantu seseorang,

Anda bisa mendapatkan output baris dari ini dan memformat objek row_date seperti yang Anda inginkan.

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

Berikut adalah metode kalengan yang akan menerima tanggal atau string Moment atau campuran sebagai input dan menghasilkan array tanggal sebagai tanggal Moment. Jika Anda tidak ingin tanggal Momen sebagai output maka ubah map()metode apa yang dikembalikan.

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

@ solusi softvar, tetapi kemudian termasuk opsi tanggal kerja

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

Fungsi:

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

Pemakaian:

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

Semoga ini bisa membantu Anda

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.