Как рассчитать разницу в месяцах между двумя датами в C #?
Есть ли эквивалентный DateDiff()
метод VB в C #. Мне нужно найти разницу в месяцах между двумя датами, которые разделены годами. Документация говорит, что я могу использовать TimeSpan
как:
TimeSpan ts = date1 - date2;
но это дает мне данные в днях. Я не хочу делить это число на 30, потому что не каждый месяц равен 30 дням, и так как два значения операндов довольно сильно отличаются друг от друга, я боюсь, что деление на 30 может дать мне неправильное значение.
Какие-либо предложения?
DateDiff
имплантация: referenceource.microsoft.com/#Microsoft.VisualBasic/… .Ответы:
Предполагая, что день месяца не имеет значения (т.е. разница между 2011.1.1 и 2010.12.31 равна 1), при этом date1> date2 дает положительное значение, а date2> date1 отрицательное значение
Или, если вы хотите приблизительное количество «средних месяцев» между двумя датами, следующее должно работать для всех, кроме очень больших разниц в датах.
Обратите внимание, что если вы должны использовать последнее решение, тогда в ваших модульных тестах должен быть указан самый широкий диапазон дат, с которым ваше приложение предназначено для работы, и соответствующим образом подтвердить результаты расчета.
Обновление (с благодарностью Гэри )
При использовании метода «средних месяцев» чуть более точное число для «среднего числа дней в году» составляет 365,2425 .
источник
(date1.Year - date2.Year) * 12 + date1.Month - date2.Month + (date1.Day >= date2.Day ? 0 : -1)
Здесь представлено комплексное решение для возврата a
DateTimeSpan
, аналогичное aTimeSpan
, за исключением того, что оно включает все компоненты даты в дополнение к компонентам времени.Использование:
Выходы:
Для удобства я включил логику в
DateTimeSpan
структуру, но вы можете перемещать методCompareDates
там, где считаете нужным. Также обратите внимание, что не имеет значения, какая дата предшествует другой.источник
34
дни этой разницы времени дата на самом деле это35
timeanddate.com/date/...31
и с датой, которая проходит через месяцы с меньшим количеством дней. Я перевернул логику (так что она идет от раннего к более позднему, чем наоборот) и теперь накапливает месяцы без изменения текущей даты (и, таким образом, проходя через месяцы с меньшим количеством дней). До сих пор не совсем уверен, какой идеальный результат должно быть при сравнении10/31/2012
с11/30/2012
. Прямо сейчас результат1
месяц.2020-02-29
к2021-06-29
- она возвращает «1y ого 1d», но значение должно быть «1y ого 0d», верно?Вы могли бы сделать
источник
if ( date1.AddMonths(x).Month == date2.Month )
тогда вы просто используете x + 1 для подсчета месяцевЕсли вам нужно точное число полных месяцев, всегда положительное (2000-01-15, 2000-02-14 возвращает 0), учитывая, что полный месяц - это когда вы достигаете того же дня в следующем месяце (что-то вроде расчета возраста)
Изменить причину: старый код был неправильным в некоторых случаях, таких как:
источник
new { From = new DateTime(2015, 12, 31), To = new DateTime(2015, 6, 30), Result = 6 }
тест неnew { From = new DateTime(2015, 12, 31), To = new DateTime(2016, 06, 30), Result = 6 }
. «Ошибка» заключается вto.Day < from.Day
коде, который не учитывает, что месяцы могут заканчиваться другим «днем месяца». В этом случае с 31 декабря 2015 года до 30 июня 2016 года пройдет 6 полных месяцев (с июня 30 дней), но ваш код вернется 5.Я проверил использование этого метода в VB.NET через MSDN, и кажется, что он имеет много применений. В C # такого встроенного метода нет. (Даже это не очень хорошая идея) вы можете вызывать VB в C #.
Microsoft.VisualBasic.dll
в свой проект в качестве ссылкиMicrosoft.VisualBasic.DateAndTime.DateDiff
в своем кодеисточник
Microsoft.VisualBasic.dll
модуль должен быть загружен, но время, которое требуется для этого, незначительно. Нет причин обманывать себя проверенными и полезными функциями только потому, что вы решили написать свою программу на C #. (Это относится и к таким вещамMy.Application.SplashScreen
.)using
утверждением, но я сомневаюсь, что будет какой-либо серьезный ущерб.DateAndTime.Year()
существования, учитывая, что уDateTime
него естьYear
свойство. Он существует только для того, чтобы VB.NET выглядел больше как VB6. Как бывший программист VB6, я могу это оценить ;-)Чтобы получить разницу в месяцах (включая начало и конец включительно), независимо от дат:
источник
start
иend
идентичны. Тогда вы получите результат 1. Как это правильно? Почему вы добавляете 1 к результату? Кто голосует против этого ответа: - /?Используйте время Noda :
(пример источника)
источник
Мне просто нужно было что-то простое, чтобы удовлетворить, например, даты трудоустройства, когда вводится только месяц / год, поэтому хотел, чтобы работали разные годы и месяцы. Это то, что я использую, здесь только для пользы
.NET Fiddle
источник
Вы можете использовать класс DateDiff библиотеки периодов времени для .NET :
источник
Вот мой вклад, чтобы получить разницу в месяцах, которые я считаю точными:
Использование:
Вы можете создать другой метод с именем DiffYears и применить точно такую же логику, что и выше, и AddYears вместо AddMonths в цикле while.
источник
Это сработало для того, что мне было нужно. В моем случае день месяца не имел значения, потому что это всегда последний день месяца.
источник
Самый точный способ - это вернуть разницу в месяцах по доле:
источник
Вот простое решение, которое работает по крайней мере для меня. Это, вероятно, не самый быстрый, потому что он использует классную функцию AddTonth DateTime в цикле:
источник
источник
Это из моей собственной библиотеки, вернет разницу месяцев между двумя датами.
источник
Jan-31-2014
иDec-31-2013
Вы можете иметь функцию примерно так.
Например, с 2012/12/27 по 2012/12/29 становится 3 дня. Аналогичным образом, с 2012/12/15 по 2013/15/15 становится 2 месяца, потому что до 2013/01/14 это 1 месяц. с 15го месяца начался 2й месяц
Вы можете удалить «=» во втором условии if, если вы не хотите включать в расчет оба дня. т.е. с 2012/12/15 по 2013/15/15 составляет 1 месяц.
источник
Вы можете использовать следующее расширение: Код
Реализация !
источник
Вот гораздо более краткое решение, использующее VB.Net DateDiff только для года, месяца, дня. Вы также можете загрузить библиотеку DateDiff в C #.
дата1 должна быть <= дата2
VB.NET
C #
источник
Это в ответ на ответ Кирка Уолла. У меня недостаточно очков репутации, чтобы ответить на комментарий ...
Мне понравилось решение Кирка, и я собирался бесстыдно сорвать его и использовать в своем коде, но когда я просмотрел его, я понял, что это слишком сложно. Ненужные переключения и циклы, а также открытый конструктор, который бессмысленно использовать.
Вот мой переписать:
Использование1, почти то же самое:
Использование2, аналогично:
источник
В моем случае требуется рассчитать полный месяц от даты начала до дня, предшествующего этому дню в следующем месяце или от начала до конца месяца.
Пример: с 1 января по 31 января 2008 года - полный месяц
Пример 2: с 1 мая по 2 февраля 2008 года - полный месяц
поэтому на основе этого вот мое решение:
Использование:
Примечание: в моем случае требовалось рассчитать оставшиеся дни после полных месяцев, поэтому, если это не ваш случай, вы можете проигнорировать результат дней или даже изменить метод return с кортежа на целое число.
источник
Это решение для расчета аренды / подписки, где разница не означает вычитание, а промежуток между этими двумя датами.
источник
Есть 3 случая: тот же год, предыдущий год и другие годы.
Если день месяца не имеет значения ...
источник
Я написал функцию для достижения этой цели, потому что другие способы не работали для меня.
источник
Мое понимание общей разницы в месяцах между двумя датами имеет неотъемлемую и дробную часть (дата имеет значение).
Неотъемлемой частью является полная месячная разница.
Дробная часть, для меня, это разница в процентах от дня (до полных дней месяца) между начальным и конечным месяцами.
С этим расширением таковы результаты:
источник
На этот вопрос не так много четких ответов, потому что вы всегда принимаете вещи.
Это решение вычисляет между двумя датами месяцы между ними, предполагая, что вы хотите сохранить день месяца для сравнения (это означает, что день месяца учитывается при расчете)
Например, если у вас дата 30 января 2012 года, 29 февраля 2012 года будет не месяцем, а 01 марта 2013 года.
Он был довольно тщательно протестирован, возможно, позже мы его очистим, но здесь:
источник
Основываясь на превосходной работе DateTimeSpan, проделанной выше, я немного нормализовал код; это, кажется, работает довольно хорошо:
источник
CompareDates(x, y)
гдеx={01/02/2019 00:00:00}
иy={01/05/2020 00:00:00}
затемMonths
дает мне2
Эта простая статическая функция вычисляет долю месяцев между двумя датами, например
Функция предполагает, что первая дата меньше второй даты. Чтобы справиться с отрицательными временными интервалами, можно легко изменить функцию, введя знак и переменную swap в начале.
источник
Чтобы иметь возможность рассчитать разницу между двумя датами в месяцах, это совершенно логичная вещь, которая необходима во многих бизнес-приложениях. Несколько кодеров, которые предоставили комментарии, такие как - какая разница в месяцах между «май 1,2010» и «16,2010 июня», какая разница в месяцах между 31 декабря 2010 года и 1 января 2011 года? - не смогли понять самые основы бизнес-приложений.
Вот ответ на 2 вышеупомянутых комментария - Количество месяцев между 1 мая 2010 года и 16 июня 2010 года составляет 1 месяц, количество месяцев между 31 декабря 2010 года и 1 января 2011 года равно 0. Это было бы очень глупо вычислять их как 1,5 месяца и 1 секунду, как предложили кодеры выше.
Люди, которые работали над кредитной картой, обработкой ипотеки, обработкой налогов, обработкой арендной платы, ежемесячными расчетами процентов и множеством других бизнес-решений, согласились бы.
Проблема в том, что такая функция не включена в C # или VB.NET в этом отношении. Datediff учитывает только годы или компонент месяца, поэтому фактически бесполезен.
Вот несколько реальных примеров того, как вам нужно и как правильно рассчитать месяцы:
Вы жили в краткосрочной аренде с 18 февраля по 23 августа. Сколько месяцев вы там пробыли? Ответ прост - 6 месяцев
У вас есть банковский счет, на котором проценты начисляются и выплачиваются в конце каждого месяца. Вы вносите деньги 10 июня и снимаете их 29 октября (в том же году). Сколько месяцев вы интересуетесь? Очень простой ответ - 4 месяца (опять же лишние дни не имеют значения)
В бизнес-приложениях большую часть времени, когда вам нужно рассчитывать месяцы, это происходит потому, что вам нужно знать «полные» месяцы на основе того, как люди рассчитывают время; не основанный на некоторых абстрактных / не относящихся к делу мыслях.
источник
Расширенная структура Киркс с ToString (формат) и продолжительностью (длинные мс)
источник
источник