JavaScript'teki iki Date () nesnesi için farkı nasıl hesaplayabilirim, ancak farktaki ay sayısını döndürürüm?
Herhangi bir yardım harika olurdu :)
JavaScript'teki iki Date () nesnesi için farkı nasıl hesaplayabilirim, ancak farktaki ay sayısını döndürürüm?
Herhangi bir yardım harika olurdu :)
Yanıtlar:
"Farkdaki ayların sayısı" tanımı çok fazla yoruma tabidir. :-)
Yıl, ay ve ayın günlerini bir JavaScript tarih nesnesinden alabilirsiniz. Aradığınız bilgiye bağlı olarak, bunları iki nokta arasında kaç ay olduğunu bulmak için kullanabilirsiniz.
Örneğin, manşet dışı:
function monthDiff(d1, d2) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth();
months += d2.getMonth();
return months <= 0 ? 0 : months;
}
(JavaScript'teki ay değerlerinin 0 = Ocak ile başladığını unutmayın.)
Yukarıdaki kesirli ayları dahil etmek çok daha karmaşıktır, çünkü tipik bir Şubat'taki üç gün, Ağustos ayındaki üç günden (~% 9.677) daha büyük bir kesirdir (~% 10.714) ve elbette Şubat bile hareketli bir hedeftir artık bir yıl olup olmadığına bağlı.
JavaScript için bu tür şeyleri kolaylaştıran bazı tarih ve saat kütüphaneleri de vardır.
Not : + 1
Yukarıda, yukarıda a vardı:
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
// −−−−−−−−−−−−−−−−−−−−^^^^
months += d2.getMonth();
Çünkü başlangıçta dedim ki:
... bu, kısmi ayları hesaba katmadan iki tarih arasında kaç tam ay bulunduğunu öğrenir (örneğin, her bir tarihin bulunduğu ay hariç).
İki nedenden dolayı kaldırdım:
Kısmi ayları saymamak, cevaba gelen birçok kişinin (en çok?) İstediği değil, bu yüzden onları ayırmam gerektiğini düşündüm.
Bu tanımla bile her zaman işe yaramadı. :-D (Üzgünüm.)
Ayın gününü düşünmüyorsanız, bu daha basit bir çözümdür
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
Ay endeksinin 0 tabanlı olduğunu unutmayın. Bu demektir ki January = 0
ve December = 11
.
Bazen iki tarih arasındaki ay miktarını gün bölümünü tamamen görmezden gelmek isteyebilirsiniz. Örneğin, iki tarihiniz varsa - 2013/06/21 ve 2013/10 / 18- ve sadece 2013/06 ve 2013/10 bölümlerini önemsediyseniz, senaryolar ve olası çözümler şunlardır:
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. hem ay1 hem de ay hariç iki tarih arasındaki ay sayısını istiyorsanız2
numberOfMonths = (year2 - year1) * 12 + (month2 - month1) - 1;
2. aylardan birini dahil etmek istiyorsanız
numberOfMonths = (year2 - year1) * 12 + (month2 - month1);
3.Her iki ayı da dahil etmek istiyorsanız
numberOfMonths = (year2 - year1) * 12 + (month2 - month1) + 1;
numberOfMonths=(year2-year1)*12+(month2-month1)+1;
aynı şeyi yapıyor ama benim için daha anlamsal olarak doğru
İşte 2 tarih arasındaki ay sayısını doğru bir şekilde sağlayan bir işlev.
Varsayılan davranış yalnızca tüm ayları sayar, örneğin 3 ay ve 1 gün 3 ay farkla sonuçlanır. roundUpFractionalMonths
Parametreyi şu şekilde ayarlayarak bunu önleyebilirsiniz true
, böylece 3 ay ve 1 günlük fark 4 ay olarak döndürülür.
Yukarıdaki kabul edilen cevap (TJ Crowder'ın cevabı) doğru değil, bazen yanlış değerler döndürüyor.
Örneğin , açıkça yanlış olan monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015'))
döndürür 0
. Doğru fark 1 tam ay veya 2 ay boyunca toplanır.
İşte yazdığım fonksiyon:
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);
};
Ayın 28, 29, 30 veya 31 gün olmasına bakılmaksızın tam ayları saymanız gerekiyorsa. Aşağıda çalışması gerekir.
var months = to.getMonth() - from.getMonth()
+ (12 * (to.getFullYear() - from.getFullYear()));
if(to.getDate() < from.getDate()){
months--;
}
return months;
Bu, https://stackoverflow.com/a/4312956/1987208 yanıtının genişletilmiş bir sürümüdür, ancak 31 Ocak ile 1 Şubat (1 gün) arasındaki dava için 1 ay hesapladığı durumu düzeltir.
Bu aşağıdakileri kapsayacaktır;
JavaScript'te iki tarih arasındaki Aylar arasındaki fark:
start_date = new Date(year, month, day); //Create start date object by passing appropiate argument
end_date = new Date(new Date(year, month, day)
başlangıç_tarihi ile bitiş_tarihi arasındaki toplam aylar:
total_months = (end_date.getFullYear() - start_date.getFullYear())*12 + (end_date.getMonth() - start_date.getMonth())
Bunun gerçekten geç olduğunu biliyorum, ama başkalarına yardım etmesi durumunda yine de gönderiyorum. Burada, iki tarih arasındaki aylarda farklılıkları saymak için iyi bir iş çıkardığı bir fonksiyon var. Kuşkusuz Mr.Crowder'ınkinden çok daha ılımlı ama tarih nesnesine adım atarak daha doğru sonuçlar veriyor. AS3'te ancak güçlü yazmayı bırakabilmeniz gerekir ve JS'ye sahip olursunuz. Orada kimse arıyor güzel yapmaktan çekinmeyin!
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;
}
@ TJ'nin cevabını genişletmek için, tam takvim ayları yerine basit aylar arıyorsanız, d2'nin tarihinin d1'den büyük veya ona eşit olup olmadığını kontrol edebilirsiniz. Yani, d2 ayının sonlarında d1 ayından daha fazlaysa, 1 ay daha vardır. Yani bunu yapabilmeniz gerekir:
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
Bu, zaman sorunlarını tamamen hesaba katmaz (örneğin, 3 Mart 16:00 ve 3 Nisan 15:00), ancak daha doğru ve sadece birkaç satır kod için.
Her tarihi ay cinsinden düşünün, ardından farkı bulmak için çıkartın.
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());
Bu, günleri yok sayarak iki tarih arasındaki ay farkını elde etmenizi sağlar.
Matematiksel ve hızlı olmakla birlikte takvimdeki değişkenlere veya yinelemeli ve yavaş olan iki yaklaşım vardır, ancak tüm tuhaflıkları (veya en azından iyi test edilmiş bir kütüphaneye yönlendiren delegeleri) ele alır.
Takvimde yineleme yaparsanız, başlangıç tarihini bir ay arttırır ve bitiş tarihini geçip geçmediğimizi görürsünüz. Bu delegeler yerleşik Date () sınıflara anomali işleme, ama yavaş olabilir EĞER tarihlere çok sayıda için yapıyoruz. James'in cevabı bu yaklaşımı benimser. Fikirden hoşlanmadığım kadarıyla, bunun "en güvenli" yaklaşım olduğunu düşünüyorum ve sadece bir hesaplama yapıyorsanız , performans farkı gerçekten ihmal edilebilir. Yalnızca bir kez gerçekleştirilecek görevleri aşırı optimize etmeye çalışırız.
Şimdi, eğer bir veri kümesi üzerinde bu işlevi hesaplama ediyoruz, muhtemelen (kayıt başına, birden çok kez ya da Allah korusun) her satır üzerinde bu işlevi çalıştırmak istemiyoruz. Bu durumda, kabul edilen cevap haricinde hemen hemen diğer tüm cevapları kullanabilirsiniz , ki bu sadece yanlıştır ( new Date()
ve new Date()
-1 arasındaki fark )?
Farklı ay uzunluklarını ve artık yılları açıklayan matematiksel ve hızlı bir yaklaşımdan sapmam. Gerçekten böyle bir işlevi yalnızca bunu bir veri kümesine uygulayacaksanız (bu hesaplamayı tekrar tekrar yaparken) kullanmalısınız. Sadece bir kez yapmanız gerekiyorsa, yukarıdaki James'in yinelemeli yaklaşımını kullanın, çünkü Date () nesnesinin tüm (çok) istisnalarını ele alırken.
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;
}
Burada daha az döngü ile başka bir yaklaşıma gidersiniz:
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;
}
Bu çözümü de düşünebilirsiniz, bu function
tam sayı veya sayıdaki ay farkını döndürür
Geçme başlangıç tarihini ilk veya son olarak param
, hataya dayanıklı olmadığını. Yani, fonksiyon yine de aynı değeri döndürür.
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);
İki tarih arasındaki farkı hesaplayın ay kesiri (gün) içerir.
var difference = (date2.getDate() - date1.getDate()) / 30 +
date2.getMonth() - date1.getMonth() +
(12 * (date2.getFullYear() - date1.getFullYear()));
Örneğin:
tarih1 : 24/09/2015 (24 Eylül 2015)
tarih2 : 09/11/2015 (9 Kasım 2015)
fark: 2,5 (ay)
Bu iyi çalışmalıdır:
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);
}
Aşağıdaki kod, kısmi ayların günlerini de dikkate alarak iki tarih arasında tam ayları döndürür.
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;
}
mantığın altındaki aylar fark getirecek
(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;
}
Ne kullandığımı görün:
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;
}
Ayrıca günleri sayar ve aylar içinde dönüştürür.
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
Bu durumda, tam aylar, bölüm aylar, bir ayın ne kadar sürdüğü vb. İle ilgilenmiyorum. Sadece ay sayısını bilmem gerekiyor. İlgili bir gerçek dünya vakası, her ay bir raporun verilmesi gereken durumdur ve kaç rapor olması gerektiğini bilmem gerekir.
Misal:
Bu, sayıların nereye gittiğini gösteren ayrıntılı bir kod örneğidir.
4 ay ile sonuçlanması gereken 2 zaman damgası alalım
Saat diliminiz / saatiniz çekildiğinde biraz farklı olabilir. Gün, dakika ve saniye önemli değildir ve zaman damgasına dahil edilebilir, ancak asıl hesaplamamızla bunu dikkate almayacağız.
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();
Bu bize
(12 * (endYear - startYear)) + 1
Bitiş ayına ekleyin .2 + (12 * (2020 - 2019)) + 1 = 15
15 - 11 = 4
; 4 aylık sonucumuzu alıyoruz.
Kasım 2019 - Mart 2022 arası 29 aydır. Bunları bir excel e-tablosuna koyarsanız, 29 satır görürsünüz.
3 + (12 * (2022-2019)) + 1
40-11 = 29
anyVar = (((DisplayTo.getFullYear() * 12) + DisplayTo.getMonth()) - ((DisplayFrom.getFullYear() * 12) + DisplayFrom.getMonth()));
Bir yaklaşım, JODA kitaplığını kullanan basit bir Java Web Hizmeti (REST / JSON) yazmak olacaktır.
http://joda-time.sourceforge.net/faq.html#datediff
iki tarih arasındaki farkı hesaplamak ve bu hizmeti javascript'ten çağırmak için.
Bu, arka ucunuzun Java'da olduğunu varsayar.