2015-09-22 2 views
1

Я не ищу ответ или фрагмент кода для вопроса в заголовке, но вместо этого я ищу помощь, чтобы понять, почему фрагмент кода не работает, как я ожидаю, :Получение месяцев между двумя датами

var getMonthsBetween = function(date1, date2) 
{ 
    'use strict'; 

    // 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 start_date = date1; 
    var end_date = date2; 
    var inverse = false; 

    if (date1 > date2) 
    { 
     start_date = date2; 
     end_date = date1; 
     inverse = true; 
    } 

    // Calculate the differences between the start and end dates 
    var yearsDifference = end_date.getFullYear() - start_date.getFullYear(); 
    var monthsDifference = end_date.getMonth() - start_date.getMonth(); 
    var daysDifference = (end_date.getDate()+1) - start_date.getDate(); // This +1 might be a mistake 

    return (inverse ? -1 : 1) * (yearsDifference * 12 + monthsDifference + daysDifference/30); // Add fractional month 
} 

Приведенный выше код предназначен, чтобы вернуть разницу (в месяцах) между 2 указанными датами, с точностью до первого десятичного знака. Я сам не писал код и не имел контакта с тем, кто его написал, к сожалению, и я не могу сказать, почему автор решил добавить день к дате окончания при разработке разницы в днях (есть случаи, когда он слегка отключен).

Не могли бы вы помочь мне с этой проблемой? Я не уверен, в чем причина добавить этот дополнительный день здесь ((end_date.getDate()+1)), и я не уверен, что это на самом деле правильно (я подозреваю, что это не так), но я хотел бы другое мнение.

EDIT я неясно как функция не работает, как ожидалось - это называется, как только пользователь выбирает 2 даты от 2 выбора даты. Рассчитанные числа не отправляются на бэкэнд, вместо этого исходные 2 даты отправляются обратно, а затем мы используем (PHP) datetime.diff, чтобы определить, сколько месяцев между датами. Бэкэнд уже подтвержден как правильный, но интерфейс не всегда соответствует ему, например.

start date = Monday June 30, 2014, 00:00:00 
end date = Saturday February 28, 2015, 00:00:00 
result (JS) = 7.933333333333334 
result (PHP datetime.diff) = 8.0333333333333 

или

start date = Tuesday June 30, 2015, 00:00:00 
end date = Monday February 29, 2016, 00:00:00 
result (JS) = 7.966666666666667 
result (PHP datetime.diff) = 8.0333333333333 

Тогда есть другие раз, когда число делать матч, например,

start date = Monday June 30, 2014, 00:00:00 
end date = Wednesday April 15, 2015, 00:00:00 
result (JS) = 9.5 
result (PHP datetime.diff) = 9.5 
+0

Это потому, что первоначальный писатель кода, возможно, подумал о дате начала, чтобы быть в начале дня и в конце дня, чтобы быть в конце дня. Поэтому при использовании одной и той же даты для даты начала и окончания он использовал соглашение, которое является разницей в один день – Dbuggy

+0

Возможный дубликат [Разница в месяцах между двумя датами в JavaScript] (http://stackoverflow.com/questions/2536379/ разница в месяцах-между-двумя-датами-в-javascript) –

+1

Что значит «код не работает, как я ожидаю, он:» может включать вывод и ваш ожидаемый результат? вы можете проследить каждое значение, чтобы узнать, почему он добавил, что 1. также проверьте значения «date1» и «date2», если он отражает фактическую дату, выбранную пользователем. –

ответ

2

Очевидно, что datetime.diff PHP содержит окончательный день в его вычислении. Когда я фактически увеличил дату окончания на стороне JavaScript, числа все совпадают. Приращение самого объекта даты до, сравнивающее их, для перехода на следующий месяц. Оригинальный разработчик заметил, что это происходит, но он не увеличил дату окончания правильно.Он добавил еще один день до значения дня даты окончания, но это не меняется на следующий месяц при добавлении в день до 28 февраля 2015

Этот код работает, как ожидалось:

var getMonthsBetween = function(date1, date2) 
{ 
    'use strict'; 

    // 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 start_date = date1; 
    var end_date = date2; 
    var inverse = false; 

    if (date1 > date2) 
    { 
     start_date = date2; 
     end_date = date1; 
     inverse = true; 
    } 

    end_date = new Date(end_date); //If you don't do this, the original date passed will be changed. Dates are mutable objects. 
    end_date.setDate(end_date.getDate() + 1); 

    // Calculate the differences between the start and end dates 
    var yearsDifference = end_date.getFullYear() - start_date.getFullYear(); 
    var monthsDifference = end_date.getMonth() - start_date.getMonth(); 
    var daysDifference = end_date.getDate() - start_date.getDate(); 

    return (inverse ? -1 : 1) * (yearsDifference * 12 + monthsDifference + daysDifference/30); // Add fractional month 
} 
+0

Спасибо, я собираюсь попробовать это и пометьте этот ответ правильно, если он сработает! – Skytiger

+0

Благодарим вас за помощь, но предоставленный вами фрагмент не повлиял на вывод функции для примеров, представленных в OP. Какова цель '! YearsDifference' и'! MonthsDifference' в этом выражении if? – Skytiger

+0

Здесь '! YearsDifference' и'! MonthsDifference' должны быть уверены, что сравниваемая дата находится в том же месяце и году. Таким образом, 22 июня и 22 апреля не обнаруживаются в тот же день. – aecend

2

Вы считаете, что это неправильно, потому что вы предположили, что обе даты: 00:00:00. Оригинальный автор думал по-другому: первая дата считается 00:00:00, последняя дата считается равной 24:00:00. (Конечно, JavaScript не имеет понятия 24:00:00).

Итак, в принципе вы оба правы, автор должен был сделать комментарий об этом.


Другой угол, глядя на это идет от немного теории чисел: вы думаете, что функция вычисляет как левых закрытой - открытый справа интервал, оригинальный автор думал о отрезке.

+0

Извинения. Я добавил примеры используемых данных. Вы можете видеть, что и начальная, и конечная даты - 00:00:00 до того, как будут выполнены какие-либо вычисления. – Skytiger

+0

Конечно, они есть. Может быть, я не был ясен. JavaScript не имеет понятия '24: 00: 00', но это не мешает разработчику думать так, как есть. Расчет отражает это: '24: 00: 00' совпадает с следующим днем ​​в 00:00 00:00. – meskobalazs