Як я можу розробити різницю для двох об’єктів Date () у JavaScript, при цьому повернути лише різницю за кілька місяців?
Будь-яка допомога була б чудовою :)
Як я можу розробити різницю для двох об’єктів Date () у JavaScript, при цьому повернути лише різницю за кілька місяців?
Будь-яка допомога була б чудовою :)
Відповіді:
Визначення "кількість місяців у різниці" піддається багато тлумачення. :-)
Ви можете отримати рік, місяць та день місяця від об’єкта дати JavaScript. Залежно від того, яку інформацію ви шукаєте, ви можете використовувати їх, щоб визначити, скільки місяців триває два моменти часу.
Наприклад, без манжети:
function monthDiff(d1, d2) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth();
months += d2.getMonth();
return months <= 0 ? 0 : months;
}
(Зверніть увагу, що місячні значення в JavaScript починаються з 0 = січень.)
Включити у зазначені вище часткові місяці набагато складніше, оскільки три дні типового лютого - це більша частка цього місяця (~ 10,714%), ніж три дні в серпні (~ 9,677%), і звичайно навіть лютий є рухомою ціллю залежно від того, чи це високосний рік.
Існують також деякі бібліотеки дати та часу для JavaScript, які, ймовірно, полегшують подібні речі.
Примітка . Раніше + 1
тут було вище:
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
// −−−−−−−−−−−−−−−−−−−−^^^^
months += d2.getMonth();
Це тому, що спочатку я сказав:
... це з’ясовує скільки повних місяців лежить між двома датами, не рахуючи часткових місяців (наприклад, виключаючи місяць, у якому кожна дата є).
Я видалив її з двох причин:
Не рахуючи часткових місяців, виявляється, не те, чого хочуть багато (більшість?) Людей, які приходять до відповіді, тому я подумав, що я повинен їх розлучити.
Це не завжди працювало навіть за цим визначенням. :-D (Вибачте)
Якщо ви не враховуєте день місяця, це набагато простіше рішення
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
Майте на увазі, що індекс місяця базується на 0. Це означає, що January = 0
і December = 11
.
Іноді ви можете отримати лише кількість місяців між двома датами, повністю ігноруючи денну частину. Так, наприклад, якщо у вас було дві дати - 2013/06/21 та 2013/10 / 18- і ви дбали лише про частини 2013/06 та 2013/10, ось такі сценарії та можливі рішення:
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.Якщо ви хочете просто кількість місяців між двома датами, виключаючи місяць1 і місяць2
numberOfMonths = (year2 - year1) * 12 + (month2 - month1) - 1;
2.Якщо ви хочете включити будь-який з місяців
numberOfMonths = (year2 - year1) * 12 + (month2 - month1);
3.Якщо ви хочете включити обидва місяці
numberOfMonths = (year2 - year1) * 12 + (month2 - month1) + 1;
numberOfMonths=(year2-year1)*12+(month2-month1)+1;
що робить те саме, але для мене більш семантично правильне
Ось функція, яка точно забезпечує кількість місяців між двома датами.
Поведінка за замовчуванням нараховує лише цілі місяці, наприклад 3 місяці та 1 день призведе до різниці в 3 місяці. Ви можете запобігти цьому, встановивши roundUpFractionalMonths
параметр як true
, тому різниця у 3 місяці та 1 день повернеться як 4 місяці.
Прийнята вище відповідь (відповідь TJ Crowder) не є точною, іноді вона повертає неправильні значення.
Наприклад, monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015'))
повернення, 0
що, очевидно, неправильно. Правильна різниця - або 1 цілий місяць, або 2 місяці округлення.
Ось функцію, яку я написав:
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);
};
Якщо вам потрібно рахувати повні місяці, незалежно від місяця, який становить 28, 29, 30 або 31 день. Нижче має працювати.
var months = to.getMonth() - from.getMonth()
+ (12 * (to.getFullYear() - from.getFullYear()));
if(to.getDate() < from.getDate()){
months--;
}
return months;
Це розширена версія відповіді https://stackoverflow.com/a/4312956/1987208 але вона фіксує випадок, коли він обчислює 1 місяць для справи з 31 січня по 1 лютого (1 день).
Це охоплює наступне;
Різниця в місяцях між двома датами в 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_months = (end_date.getFullYear() - start_date.getFullYear())*12 + (end_date.getMonth() - start_date.getMonth())
Я знаю, що це дуже пізно, але розміщувати його все одно на випадок, якщо це допомагає іншим. Ось функція, яку я придумав, яка, здається, добре справляється з підрахунком різниць у місяцях між двома датами. Це, безумовно, набагато гнучкіше, ніж у містера Кроудера, але забезпечує більш точні результати, переглядаючи об’єкт дати. Це в AS3, але ви повинні просто змогти відмовитися від сильного набору тексту, і у вас буде JS. Не соромтеся, щоб було приємніше шукати когось там!
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;
}
Розгляньте кожну дату за місяцями, а потім відніміть, щоб знайти різницю.
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());
Це дозволить отримати різницю місяців між двома датами, ігноруючи дні.
Щоб розширити відповідь @ TJ, якщо ви шукаєте прості місяці, а не повні календарні місяці, ви можете просто перевірити, чи дата d2 більша або дорівнює d1. Тобто, якщо d2 пізніше свого місяця, ніж d1 - у місяці, то є ще 1 місяць. Тож ви зможете просто зробити це:
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
Це зовсім не враховує часових питань (наприклад, 3 березня о 16:00 та 3 квітня о 15:00), але це більш точно і лише для декількох рядків коду.
Є два підходи, математичний і швидкий, але з урахуванням капризів у календарі, або ітеративних і повільних, але він обробляє всі диваки (або принаймні делегати, які обробляють їх у добре перевіреній бібліотеці).
Якщо ви повторюєте календар, збільшуючи дату початку на місяць, і бачите, чи ми перенесемо кінцеву дату. Це делегує поводження з аномаліями вбудованим класам Date (), але це може бути повільно, якщо ви робите це для великої кількості дат. Відповідь Джеймса використовує такий підхід. Наскільки мені не подобається ідея, я вважаю, що це "найбезпечніший" підхід, і якщо ви робите лише один розрахунок, різниця в продуктивності дійсно незначна. Ми схильні намагатися надмірно оптимізувати завдання, які будуть виконані лише один раз.
Тепер, якщо ви обчислюєте цю функцію на наборі даних, ви, ймовірно, не хочете запускати цю функцію в кожному рядку (або, не дай бог, кілька разів на запис). У такому випадку ви можете використовувати майже будь-яку з інших відповідей тут, крім прийнятої відповіді, що просто неправильно (різниця між new Date()
і new Date()
дорівнює -1)?
Ось мій підхід щодо математично-швидкого підходу, який пояснює різну тривалість місяця та високосні роки. Ви дійсно повинні використовувати функцію, подібну до цієї, лише якщо ви будете застосовувати це до набору даних (роблячи цей розрахунок знову і знову). Якщо вам потрібно зробити це один раз, використовуйте ітеративний підхід Джеймса вище, оскільки ви делегуєте обробку всіх (багатьох) винятків для об'єкта 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;
}
Ось вам і інший підхід із меншим циклом:
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;
}
Ви також можете розглянути це рішення, це function
повертає різницю місяця в цілому чи кількості
Передача дати початку як першої чи останньої param
є помилковою. Значить, функція все одно поверне те саме значення.
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);
Обчисліть різницю між двома датами, включаючи частку місяця (днів).
var difference = (date2.getDate() - date1.getDate()) / 30 +
date2.getMonth() - date1.getMonth() +
(12 * (date2.getFullYear() - date1.getFullYear()));
Наприклад:
date1 : 24/09/2015 (24 вересня 2015)
date2 : 09/11/2015 (9 листопада 2015)
різниця: 2.5 (місяців)
Це має добре працювати:
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);
}
Наступний код повертає повні місяці між двома датами, враховуючи також число днів часткових місяців.
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;
}
нижче логіка принесе різницю в місяцях
(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;
}
Подивіться, що я використовую:
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;
}
Він також рахує дні та перетворює їх у місяці.
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
У цьому випадку я не переймаюся повними місяцями, неповними місяцями, як тривалим місяцем і т. Д. Мені просто потрібно знати кількість місяців. Відповідним випадком у реальному світі є те, коли слід звітувати щомісяця, і мені потрібно знати, скільки звітів повинно бути.
Приклад:
Це розроблений приклад коду, щоб показати, куди йдуть цифри.
Візьмемо 2 часові позначки, які повинні призвести через 4 місяці
Можливо, дещо відрізняється залежно від вашого часового поясу / часу. День, хвилини та секунди не мають значення і можуть бути включені до часової позначки, але ми нехтуємо цим фактичним розрахунком.
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();
Це нам дає
(12 * (endYear - startYear)) + 1
до кінця місяця.2 + (12 * (2020 - 2019)) + 1 = 15
15 - 11 = 4
; ми отримуємо наш 4-місячний результат.
Листопад 2019 року по березень 2022 року - 29 місяців. Якщо ви помістите їх у таблицю Excel, ви побачите 29 рядків.
3 + (12 * (2022-2019)) + 1
40 - 11 = 29
anyVar = (((DisplayTo.getFullYear() * 12) + DisplayTo.getMonth()) - ((DisplayFrom.getFullYear() * 12) + DisplayFrom.getMonth()));
Одним із підходів було б написання простої веб-служби Java (REST / JSON), яка використовує бібліотеку JODA
http://joda-time.sourceforge.net/faq.html#dateiff
щоб обчислити різницю між двома датами та зателефонувати до цієї служби з JavaScript
Це передбачає, що ваш зворотній кінець знаходиться на Java.