Bagaimana cara mengetahui perbedaan untuk dua objek Date () di JavaScript, sementara hanya mengembalikan jumlah bulan dalam perbedaannya?
Bantuan apa pun akan sangat bagus :)
Bagaimana cara mengetahui perbedaan untuk dua objek Date () di JavaScript, sementara hanya mengembalikan jumlah bulan dalam perbedaannya?
Bantuan apa pun akan sangat bagus :)
Jawaban:
Definisi "jumlah bulan dalam perbedaan" memiliki banyak interpretasi. :-)
Anda bisa mendapatkan tahun, bulan, dan hari dalam sebulan dari objek tanggal JavaScript. Bergantung pada informasi apa yang Anda cari, Anda dapat menggunakannya untuk mengetahui berapa bulan di antara dua titik waktu.
Misalnya, off-the-cuff:
function monthDiff(d1, d2) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth();
months += d2.getMonth();
return months <= 0 ? 0 : months;
}
(Perhatikan bahwa nilai bulan dalam JavaScript dimulai dengan 0 = Januari.)
Memasukkan pecahan bulan di atas jauh lebih rumit, karena tiga hari di bulan Februari yang khas adalah pecahan yang lebih besar dari bulan itu (~ 10.714%) daripada tiga hari di bulan Agustus (~ 9.677%), dan tentu saja bahkan Februari adalah target yang bergerak. tergantung pada apakah itu tahun kabisat.
Ada juga beberapa pustaka tanggal dan waktu yang tersedia untuk JavaScript yang mungkin membuat hal semacam ini lebih mudah.
Catatan : Dulu ada + 1
di atas, di sini:
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
// −−−−−−−−−−−−−−−−−−−−^^^^
months += d2.getMonth();
Itu karena awalnya saya berkata:
... ini untuk mengetahui berapa bulan penuh yang berada di antara dua tanggal, tidak termasuk bulan parsial (misalnya, tidak termasuk bulan setiap tanggal dalam).
Saya telah menghapusnya karena dua alasan:
Tidak menghitung bulan parsial ternyata tidak menjadi apa yang diinginkan banyak (kebanyakan?) Orang yang datang ke jawaban, jadi saya pikir saya harus memisahkan mereka.
Itu tidak selalu berhasil bahkan dengan definisi itu. :-D (Maaf.)
Jika Anda tidak mempertimbangkan hari dalam sebulan, ini adalah solusi yang jauh lebih sederhana
function monthDiff(dateFrom, dateTo) {
return dateTo.getMonth() - dateFrom.getMonth() +
(12 * (dateTo.getFullYear() - dateFrom.getFullYear()))
}
//examples
console.log(monthDiff(new Date(2000, 01), new Date(2000, 02))) // 1
console.log(monthDiff(new Date(1999, 02), new Date(2000, 02))) // 12 full year
console.log(monthDiff(new Date(2009, 11), new Date(2010, 0))) // 1
Ketahuilah bahwa indeks bulan berbasis 0. Ini berarti January = 0
dan December = 11
.
Kadang-kadang Anda mungkin ingin mendapatkan jumlah bulan di antara dua tanggal yang sama sekali mengabaikan bagian hari. Jadi misalnya, jika Anda memiliki dua tanggal- 2013/06/21 dan 2013/10 / 18- dan Anda hanya peduli tentang bagian 2013/06 dan 2013/10, berikut adalah skenario dan kemungkinan solusi:
var date1=new Date(2013,5,21);//Remember, months are 0 based in JS
var date2=new Date(2013,9,18);
var year1=date1.getFullYear();
var year2=date2.getFullYear();
var month1=date1.getMonth();
var month2=date2.getMonth();
if(month1===0){ //Have to take into account
month1++;
month2++;
}
var numberOfMonths;
1.Jika Anda hanya menginginkan jumlah bulan antara dua tanggal tidak termasuk bulan1 dan bulan2
numberOfMonths = (year2 - year1) * 12 + (month2 - month1) - 1;
2. Jika Anda ingin memasukkan salah satu bulan
numberOfMonths = (year2 - year1) * 12 + (month2 - month1);
3. Jika Anda ingin memasukkan kedua bulan tersebut
numberOfMonths = (year2 - year1) * 12 + (month2 - month1) + 1;
numberOfMonths=(year2-year1)*12+(month2-month1)+1;
mana yang melakukan hal yang sama tetapi lebih semantik benar bagi saya
Berikut adalah fungsi yang secara akurat memberikan jumlah bulan antara 2 tanggal.
Perilaku default hanya menghitung bulan penuh, misalnya 3 bulan dan 1 hari akan menghasilkan perbedaan 3 bulan. Anda dapat mencegah hal ini dengan mengatur roundUpFractionalMonths
param sebagai true
, sehingga perbedaan 3 bulan dan 1 hari akan dikembalikan sebagai 4 bulan.
Jawaban yang diterima di atas (jawaban TJ Crowder) tidak akurat, terkadang mengembalikan nilai yang salah.
Misalnya, monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015'))
pengembalian 0
yang jelas-jelas salah. Perbedaan yang benar adalah 1 bulan penuh atau 2 bulan pembulatan.
Inilah fungsi yang saya tulis:
function getMonthsBetween(date1,date2,roundUpFractionalMonths)
{
//Months will be calculated between start and end dates.
//Make sure start date is less than end date.
//But remember if the difference should be negative.
var startDate=date1;
var endDate=date2;
var inverse=false;
if(date1>date2)
{
startDate=date2;
endDate=date1;
inverse=true;
}
//Calculate the differences between the start and end dates
var yearsDifference=endDate.getFullYear()-startDate.getFullYear();
var monthsDifference=endDate.getMonth()-startDate.getMonth();
var daysDifference=endDate.getDate()-startDate.getDate();
var monthCorrection=0;
//If roundUpFractionalMonths is true, check if an extra month needs to be added from rounding up.
//The difference is done by ceiling (round up), e.g. 3 months and 1 day will be 4 months.
if(roundUpFractionalMonths===true && daysDifference>0)
{
monthCorrection=1;
}
//If the day difference between the 2 months is negative, the last month is not a whole month.
else if(roundUpFractionalMonths!==true && daysDifference<0)
{
monthCorrection=-1;
}
return (inverse?-1:1)*(yearsDifference*12+monthsDifference+monthCorrection);
};
Jika Anda perlu menghitung bulan penuh, terlepas dari bulan itu 28, 29, 30, atau 31 hari. Di bawah ini harus bekerja.
var months = to.getMonth() - from.getMonth()
+ (12 * (to.getFullYear() - from.getFullYear()));
if(to.getDate() < from.getDate()){
months--;
}
return months;
Ini adalah versi tambahan dari jawaban https://stackoverflow.com/a/4312956/1987208 tetapi memperbaiki kasus ketika ia menghitung 1 bulan untuk kasus dari 31 Januari hingga 1 Februari (1 hari).
Ini akan mencakup hal-hal berikut;
Perbedaan dalam Bulan antara dua tanggal di JavaScript:
start_date = new Date(year, month, day); //Create start date object by passing appropiate argument
end_date = new Date(new Date(year, month, day)
total bulan antara start_date dan end_date:
total_months = (end_date.getFullYear() - start_date.getFullYear())*12 + (end_date.getMonth() - start_date.getMonth())
Saya tahu ini sangat terlambat, tetapi tetap mempostingnya kalau-kalau itu membantu orang lain. Ini adalah fungsi yang saya buat yang tampaknya melakukan pekerjaan yang baik dalam menghitung perbedaan bulan antara dua tanggal. Memang jauh lebih cabul daripada Mr. Crowder, tetapi memberikan hasil yang lebih akurat dengan menelusuri objek tanggal. Ini ada di AS3 tetapi Anda seharusnya bisa melepaskan pengetikan yang kuat dan Anda akan memiliki JS. Jangan ragu untuk membuatnya lebih bagus dengan melihat siapa pun di luar sana!
function countMonths ( startDate:Date, endDate:Date ):int
{
var stepDate:Date = new Date;
stepDate.time = startDate.time;
var monthCount:int;
while( stepDate.time <= endDate.time ) {
stepDate.month += 1;
monthCount += 1;
}
if ( stepDate != endDate ) {
monthCount -= 1;
}
return monthCount;
}
Untuk memperluas jawaban @ TJ, jika Anda mencari bulan sederhana, daripada bulan kalender penuh, Anda bisa memeriksa apakah tanggal d2 lebih besar dari atau sama dengan dari d1. Artinya, jika d2 lebih lambat pada bulannya dari pada d1 pada bulannya, maka ada 1 bulan lagi. Jadi, Anda seharusnya bisa melakukan ini:
function monthDiff(d1, d2) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
months += d2.getMonth();
// edit: increment months if d2 comes later in its month than d1 in its month
if (d2.getDate() >= d1.getDate())
months++
// end edit
return months <= 0 ? 0 : months;
}
monthDiff(
new Date(2008, 10, 4), // November 4th, 2008
new Date(2010, 2, 12) // March 12th, 2010
);
// Result: 16; 4 Nov – 4 Dec '08, 4 Dec '08 – 4 Dec '09, 4 Dec '09 – 4 March '10
Ini tidak sepenuhnya memperhitungkan masalah waktu (mis. 3 Maret pukul 16:00 dan 3 April pada pukul 15:00), tetapi lebih akurat dan hanya untuk beberapa baris kode.
Pertimbangkan setiap tanggal dalam satuan bulan, lalu kurangi untuk menemukan perbedaannya.
var past_date = new Date('11/1/2014');
var current_date = new Date();
var difference = (current_date.getFullYear()*12 + current_date.getMonth()) - (past_date.getFullYear()*12 + past_date.getMonth());
Ini akan memberi Anda perbedaan bulan antara kedua tanggal tersebut, mengabaikan hari.
Anda juga dapat mempertimbangkan solusi ini, ini function
mengembalikan perbedaan bulan dalam bilangan bulat atau angka
Meneruskan tanggal mulai sebagai yang pertama atau terakhir param
, adalah toleransi kesalahan. Artinya, fungsinya masih akan mengembalikan nilai yang sama.
const diffInMonths = (end, start) => {
var timeDiff = Math.abs(end.getTime() - start.getTime());
return Math.round(timeDiff / (2e3 * 3600 * 365.25));
}
const result = diffInMonths(new Date(2015, 3, 28), new Date(2010, 1, 25));
// shows month difference as integer/number
console.log(result);
Ada dua pendekatan, matematis & cepat, tetapi dapat berubah-ubah di kalender, atau berulang & lambat, tetapi menangani semua keanehan (atau setidaknya delegasi menangani mereka ke perpustakaan yang teruji dengan baik).
Jika Anda mengulang melalui kalender, menambah tanggal mulai satu bulan & melihat apakah kami melewati tanggal akhir. Ini mendelegasikan penanganan anomali ke kelas Date () bawaan, tetapi bisa lambat JIKA Anda melakukan ini untuk sejumlah besar tanggal. Jawaban James mengambil pendekatan ini. Meskipun saya tidak menyukai idenya, saya pikir ini adalah pendekatan yang "paling aman", dan jika Anda hanya melakukan satu perhitungan, perbedaan kinerja benar-benar dapat diabaikan. Kami cenderung mencoba terlalu mengoptimalkan tugas yang hanya akan dilakukan sekali.
Sekarang, jika Anda menghitung fungsi ini pada kumpulan data, Anda mungkin tidak ingin menjalankan fungsi itu di setiap baris (atau Tuhan melarang, beberapa kali per catatan). Dalam hal ini, Anda dapat menggunakan hampir semua jawaban lain di sini kecuali jawaban yang diterima, yang salah (perbedaan antara new Date()
dan new Date()
-1)?
Inilah tusukan saya pada pendekatan matematis dan cepat, yang menjelaskan panjang bulan dan tahun kabisat yang berbeda. Anda seharusnya hanya menggunakan fungsi seperti ini jika Anda akan menerapkan ini ke kumpulan data (melakukan perhitungan ini berulang-ulang). Jika Anda hanya perlu melakukannya sekali, gunakan pendekatan iteratif James di atas, saat Anda mendelegasikan penanganan semua (banyak) pengecualian ke objek Date ().
function diffInMonths(from, to){
var months = to.getMonth() - from.getMonth() + (12 * (to.getFullYear() - from.getFullYear()));
if(to.getDate() < from.getDate()){
var newFrom = new Date(to.getFullYear(),to.getMonth(),from.getDate());
if (to < newFrom && to.getMonth() == newFrom.getMonth() && to.getYear() %4 != 0){
months--;
}
}
return months;
}
Di sini Anda pergi pendekatan lain dengan lebih sedikit perulangan:
calculateTotalMonthsDifference = function(firstDate, secondDate) {
var fm = firstDate.getMonth();
var fy = firstDate.getFullYear();
var sm = secondDate.getMonth();
var sy = secondDate.getFullYear();
var months = Math.abs(((fy - sy) * 12) + fm - sm);
var firstBefore = firstDate > secondDate;
firstDate.setFullYear(sy);
firstDate.setMonth(sm);
firstBefore ? firstDate < secondDate ? months-- : "" : secondDate < firstDate ? months-- : "";
return months;
}
Hitung selisih antara dua tanggal termasuk pecahan bulan (hari).
var difference = (date2.getDate() - date1.getDate()) / 30 +
date2.getMonth() - date1.getMonth() +
(12 * (date2.getFullYear() - date1.getFullYear()));
Contoh:
tanggal1 : 24/09/2015 (24 Sept 2015)
tanggal2 : 09/11/2015 (9 Nov 2015)
perbedaannya: 2.5 (bulan)
Ini seharusnya bekerja dengan baik:
function monthDiff(d1, d2) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months += d2.getMonth() - d1.getMonth();
return months;
}
function calcualteMonthYr(){
var fromDate =new Date($('#txtDurationFrom2').val()); //date picker (text fields)
var toDate = new Date($('#txtDurationTo2').val());
var months=0;
months = (toDate.getFullYear() - fromDate.getFullYear()) * 12;
months -= fromDate.getMonth();
months += toDate.getMonth();
if (toDate.getDate() < fromDate.getDate()){
months--;
}
$('#txtTimePeriod2').val(months);
}
Kode berikut mengembalikan bulan penuh antara dua tanggal dengan memperhitungkan juga hari dari sebagian bulan.
var monthDiff = function(d1, d2) {
if( d2 < d1 ) {
var dTmp = d2;
d2 = d1;
d1 = dTmp;
}
var months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
months += d2.getMonth();
if( d1.getDate() <= d2.getDate() ) months += 1;
return months;
}
monthDiff(new Date(2015, 01, 20), new Date(2015, 02, 20))
> 1
monthDiff(new Date(2015, 01, 20), new Date(2015, 02, 19))
> 0
monthDiff(new Date(2015, 01, 20), new Date(2015, 01, 22))
> 0
function monthDiff(d1, d2) {
var months, d1day, d2day, d1new, d2new, diffdate,d2month,d2year,d1maxday,d2maxday;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
months += d2.getMonth();
months = (months <= 0 ? 0 : months);
d1day = d1.getDate();
d2day = d2.getDate();
if(d1day > d2day)
{
d2month = d2.getMonth();
d2year = d2.getFullYear();
d1new = new Date(d2year, d2month-1, d1day,0,0,0,0);
var timeDiff = Math.abs(d2.getTime() - d1new.getTime());
diffdate = Math.abs(Math.ceil(timeDiff / (1000 * 3600 * 24)));
d1new = new Date(d2year, d2month, 1,0,0,0,0);
d1new.setDate(d1new.getDate()-1);
d1maxday = d1new.getDate();
months += diffdate / d1maxday;
}
else
{
if(!(d1.getMonth() == d2.getMonth() && d1.getFullYear() == d2.getFullYear()))
{
months += 1;
}
diffdate = d2day - d1day + 1;
d2month = d2.getMonth();
d2year = d2.getFullYear();
d2new = new Date(d2year, d2month + 1, 1, 0, 0, 0, 0);
d2new.setDate(d2new.getDate()-1);
d2maxday = d2new.getDate();
months += diffdate / d2maxday;
}
return months;
}
logika di bawah ini akan mengambil perbedaan dalam beberapa bulan
(endDate.getFullYear()*12+endDate.getMonth())-(startDate.getFullYear()*12+startDate.getMonth())
function monthDiff(date1, date2, countDays) {
countDays = (typeof countDays !== 'undefined') ? countDays : false;
if (!date1 || !date2) {
return 0;
}
let bigDate = date1;
let smallDate = date2;
if (date1 < date2) {
bigDate = date2;
smallDate = date1;
}
let monthsCount = (bigDate.getFullYear() - smallDate.getFullYear()) * 12 + (bigDate.getMonth() - smallDate.getMonth());
if (countDays && bigDate.getDate() < smallDate.getDate()) {
--monthsCount;
}
return monthsCount;
}
Lihat apa yang saya gunakan:
function monthDiff() {
var startdate = Date.parseExact($("#startingDate").val(), "dd/MM/yyyy");
var enddate = Date.parseExact($("#endingDate").val(), "dd/MM/yyyy");
var months = 0;
while (startdate < enddate) {
if (startdate.getMonth() === 1 && startdate.getDate() === 28) {
months++;
startdate.addMonths(1);
startdate.addDays(2);
} else {
months++;
startdate.addMonths(1);
}
}
return months;
}
Itu juga menghitung hari dan mengubahnya dalam bulan.
function monthDiff(d1, d2) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12; //calculates months between two years
months -= d1.getMonth() + 1;
months += d2.getMonth(); //calculates number of complete months between two months
day1 = 30-d1.getDate();
day2 = day1 + d2.getDate();
months += parseInt(day2/30); //calculates no of complete months lie between two dates
return months <= 0 ? 0 : months;
}
monthDiff(
new Date(2017, 8, 8), // Aug 8th, 2017 (d1)
new Date(2017, 12, 12) // Dec 12th, 2017 (d2)
);
//return value will be 4 months
Dalam hal ini, saya tidak peduli dengan bulan penuh, setengah bulan, berapa lama sebulan, dll. Saya hanya perlu mengetahui jumlah bulan. Kasus dunia nyata yang relevan adalah saat laporan harus jatuh tempo setiap bulan, dan saya perlu tahu berapa banyak laporan yang seharusnya ada.
Contoh:
Ini adalah contoh kode yang diuraikan untuk menunjukkan ke mana arah angka-angka tersebut.
Mari kita ambil 2 cap waktu yang seharusnya menghasilkan 4 bulan
Mungkin sedikit berbeda dengan zona waktu / waktu yang Anda tarik. Hari, menit, dan detik tidak penting dan dapat dimasukkan dalam stempel waktu, tetapi kami akan mengabaikannya dengan perhitungan aktual kami.
let dateRangeStartConverted = new Date(1573621200000);
let dateRangeEndConverted = new Date(1582261140000);
let startingMonth = dateRangeStartConverted.getMonth();
let startingYear = dateRangeStartConverted.getFullYear();
let endingMonth = dateRangeEndConverted.getMonth();
let endingYear = dateRangeEndConverted.getFullYear();
Ini memberi kita
(12 * (endYear - startYear)) + 1
ke bulan akhir.2 + (12 * (2020 - 2019)) + 1 = 15
15 - 11 = 4
; kami mendapatkan hasil 4 bulan kami.
November 2019 hingga Maret 2022 adalah 29 bulan. Jika Anda memasukkan ini ke dalam spreadsheet excel, Anda akan melihat 29 baris.
3 + (12 * (2022-2019)) + 1
40 - 11 = 29
getMonthDiff(d1, d2) {
var year1 = dt1.getFullYear();
var year2 = dt2.getFullYear();
var month1 = dt1.getMonth();
var month2 = dt2.getMonth();
var day1 = dt1.getDate();
var day2 = dt2.getDate();
var months = month2 - month1;
var years = year2 -year1
days = day2 - day1;
if (days < 0) {
months -= 1;
}
if (months < 0) {
months += 12;
}
return months + years*!2;
}
Nilai apa pun dikembalikan bersama dengan nilai absolutnya.
function differenceInMonths() {
if (firstDate > secondDate) [firstDate, secondDate] = [secondDate, firstDate];
let diffMonths = (secondDate.getFullYear() - firstDate.getFullYear()) * 12;
diffMonths -= firstDate.getMonth();
diffMonths += secondDate.getMonth();
return diffMonths;
}
firstDate
dan secondDate
ke dalam parameter fungsi Anda.
anyVar = (((DisplayTo.getFullYear() * 12) + DisplayTo.getMonth()) - ((DisplayFrom.getFullYear() * 12) + DisplayFrom.getMonth()));
Salah satu pendekatannya adalah dengan menulis Java Web Service (REST / JSON) sederhana yang menggunakan pustaka JODA
http://joda-time.sourceforge.net/faq.html#datediff
untuk menghitung perbedaan antara dua tanggal dan memanggil layanan itu dari javascript.
Ini mengasumsikan back end Anda ada di Java.