Jak obliczyć różnicę w miesiącach między dwiema datami w C #?
Czy istnieje odpowiednik metody VB DateDiff()
w C #. Muszę znaleźć różnicę w miesiącach między dwiema datami, które są latami. Dokumentacja mówi, że mogę używać TimeSpan
takich jak:
TimeSpan ts = date1 - date2;
ale to daje mi dane w dniach. Nie chcę dzielić tej liczby przez 30 ponieważ nie co miesiąc to 30 dni, a ponieważ dwie wartości operandów są zupełnie od siebie różne, obawiam się, że podzielenie przez 30 może dać mi niewłaściwą wartość.
Jakieś sugestie?
DateDiff
implantacja: referenceource.microsoft.com/#Microsoft.VisualBasic/… .Odpowiedzi:
Zakładając, że dzień miesiąca nie ma znaczenia (tzn. Różnica między 2011.1.1 a 2010.12.31 wynosi 1), przy czym data1> data2 daje wartość dodatnią, a data2> data1 wartość ujemna
Lub, zakładając, że potrzebujesz przybliżonej liczby „średnich miesięcy” między dwiema datami, poniższe powinny działać dla wszystkich oprócz bardzo dużych różnic dat.
Uwaga: jeśli chcesz użyć tego drugiego rozwiązania, testy jednostkowe powinny określać najszerszy zakres dat, z którym aplikacja ma współpracować, i odpowiednio sprawdzać wyniki obliczeń.
Aktualizacja (dzięki dzięki Gary )
W przypadku zastosowania metody „średnich miesięcy” nieco bardziej dokładna liczba dla „średniej liczby dni w roku” wynosi 365.2425 .
źródło
(date1.Year - date2.Year) * 12 + date1.Month - date2.Month + (date1.Day >= date2.Day ? 0 : -1)
Oto kompleksowe rozwiązanie do zwrotu
DateTimeSpan
, podobne doTimeSpan
, z tym wyjątkiem, że obejmuje wszystkie składniki daty oprócz składników czasu.Stosowanie:
Wyjścia:
Dla wygody skupiłem logikę na
DateTimeSpan
strukturze, ale możesz przenieść metodęCompareDates
tam, gdzie uznasz to za stosowne. Pamiętaj też, że nie ma znaczenia, która data nastąpi wcześniej.źródło
34
dni dla tej różnicy czasu i daty w rzeczywistości jest to35
timeanddate.com/date/…31
a data „mija” miesiące z mniejszą liczbą dni. Odwróciłem logikę (tak, aby przechodziła od wczesnego do późniejszego niż na odwrót) i teraz gromadzi miesiące bez zmiany bieżącej daty (i tym samym przechodząc między miesiącami z mniejszą liczbą dni) Wciąż nie do końca pewny, jaki jest idealny wynik powinno być w porównaniu10/31/2012
do11/30/2012
. W tej chwili wynikiem jest1
miesiąc.2020-02-29
się2021-06-29
- zwraca „1r 4m 1d”, ale ta wartość powinna być „1r 4m 0d”, prawda?Mógłbyś
źródło
if ( date1.AddMonths(x).Month == date2.Month )
wystarczy użyć x + 1 jako liczby miesięcyJeśli chcesz dokładną liczbę pełnych miesięcy, zawsze dodatnią (2000-01-15, 2000-02-14 zwraca 0), biorąc pod uwagę pełny miesiąc, kiedy osiągniesz ten sam dzień w następnym miesiącu (coś w rodzaju obliczenia wieku)
Edytuj powód: stary kod był nieprawidłowy w niektórych przypadkach, takich jak:
źródło
new { From = new DateTime(2015, 12, 31), To = new DateTime(2015, 6, 30), Result = 6 }
test zakończy się niepowodzeniem, ponieważ wynik to 5.new { From = new DateTime(2015, 12, 31), To = new DateTime(2016, 06, 30), Result = 6 }
. „Błąd” polega nato.Day < from.Day
kodzie, który nie bierze pod uwagę, że miesiące mogą zakończyć się innym „dniem miesiąca”. W takim przypadku od 31 grudnia 2015 r. Do 30 czerwca 2016 r. Minie 6 pełnych miesięcy (ponieważ czerwiec ma 30 dni), ale kod powróci 5.Sprawdziłem użycie tej metody w VB.NET przez MSDN i wydaje się, że ma ona wiele zastosowań. Nie ma takiej wbudowanej metody w języku C #. (Nawet nie jest to dobry pomysł) możesz wywoływać VB w C #.
Microsoft.VisualBasic.dll
do projektu jako odniesienieMicrosoft.VisualBasic.DateAndTime.DateDiff
w swoim kodzieźródło
Microsoft.VisualBasic.dll
moduł musi zostać załadowany, ale czas potrzebny na wykonanie tego jest znikomy. Nie ma powodu, aby oszukiwać się dzięki dokładnie przetestowanym i przydatnym funkcjom tylko dlatego, że zdecydowałeś się napisać swój program w języku C #. (Dotyczy to również takich rzeczyMy.Application.SplashScreen
.)using
stwierdzeniem, ale wątpię, czy to spowoduje poważne szkody.DateAndTime.Year()
aby istnieć, biorąc pod uwagę, żeDateTime
maYear
właściwość. Istnieje tylko po to, aby VB.NET wyglądał bardziej jak VB6. Jako były programista VB6 mogę to docenić ;-)Aby uzyskać różnicę w miesiącach (włącznie z początkiem i końcem), niezależnie od dat:
źródło
start
iend
są identyczne. Otrzymujesz wynik 1. Jak to prawda? Dlaczego dodajesz 1 do wyniku? Kto głosuje za odpowiedzią: - /?Użyj czasu Noda :
(przykładowe źródło)
źródło
Potrzebowałem tylko czegoś prostego do spełnienia, np. Dat zatrudnienia, w których wpisany jest tylko miesiąc / rok, więc chciałem, aby przepracowano odrębne lata i miesiące. To jest to, czego używam, tutaj tylko dla użyteczności
.NET Fiddle
źródło
Możesz użyć klasy DateDiff biblioteki okresów dla platformy .NET :
źródło
Oto mój wkład w różnicę w miesiącach, które uważam za dokładne:
Stosowanie:
Możesz utworzyć inną metodę o nazwie DiffYears i zastosować dokładnie taką samą logikę jak powyżej oraz AddYears zamiast AddMonths w pętli while.
źródło
To działało dla tego, czego potrzebowałem. Dzień miesiąca nie miał w moim przypadku znaczenia, ponieważ zawsze zdarza się, że jest to ostatni dzień miesiąca.
źródło
Najdokładniejszym sposobem jest to, aby zwracać różnicę w ułamku ułamka:
źródło
Oto proste rozwiązanie, które działa przynajmniej dla mnie. Prawdopodobnie nie jest to najszybszy, ponieważ korzysta z fajnej funkcji AddMonth DateTime w pętli:
źródło
źródło
To z mojej własnej biblioteki, zwróci różnicę miesięcy między dwiema datami.
źródło
Jan-31-2014
iDec-31-2013
Możesz mieć taką funkcję.
Na przykład od 2012/12/27 do 2012/12/29 staje się 3 dni. Podobnie od 2012/12/15 do 2013/01/15 staje się 2 miesiące, ponieważ do 2013/01/14 to 1 miesiąc. od 15. rozpoczął się drugi miesiąc.
Możesz usunąć „=” w drugim warunku, jeśli nie chcesz uwzględniać obu dni w obliczeniach. tj. od 2012/12/15 do 2013/01/15 to 1 miesiąc.
źródło
możesz użyć następującego rozszerzenia: Kod
Realizacja !
źródło
Oto o wiele bardziej zwięzłe rozwiązanie wykorzystujące VB.Net DateDiff tylko dla roku, miesiąca i dnia. Możesz także załadować bibliotekę DateDiff w języku C #.
data1 musi wynosić <= data2
VB.NET
DO#
źródło
Jest to odpowiedź na odpowiedź Kirka Wolla. Nie mam jeszcze wystarczającej liczby punktów reputacji, aby odpowiedzieć na komentarz ...
Podobało mi się rozwiązanie Kirka i zamierzam bezwstydnie go oderwać i użyć w moim kodzie, ale kiedy go przejrzałem, zdałem sobie sprawę, że jest to zbyt skomplikowane. Niepotrzebne przełączanie i zapętlanie oraz konstruktor publiczny, który nie ma sensu.
Oto moje przepisanie:
Zastosowanie 1, prawie tak samo:
Użycie 2, podobne:
źródło
W moim przypadku wymagane jest obliczenie pełnego miesiąca od daty początkowej do dnia poprzedzającego ten dzień w następnym miesiącu lub od początku do końca miesiąca.
Np .: od 1/1/2018 do 31/1/2018 to pełny miesiąc
Ex2: od 5/1/2018 do 4/2/2018 to pełny miesiąc
więc w oparciu o to oto moje rozwiązanie:
Stosowanie:
Uwaga: w moim przypadku konieczne było obliczenie pozostałych dni po pełnych miesiącach, więc jeśli nie jest to twój przypadek, możesz zignorować wynik dni lub nawet zmienić metodę powrotu z krotki na liczbę całkowitą.
źródło
To rozwiązanie służy do obliczania kosztów wynajmu / subskrypcji, w których różnica nie oznacza odejmowania, lecz ma obejmować okres w tych dwóch datach.
źródło
Istnieją 3 przypadki: ten sam rok, rok poprzedni i inne lata.
Jeśli dzień miesiąca nie ma znaczenia ...
źródło
Napisałem funkcję, aby to osiągnąć, ponieważ inne sposoby nie działały dla mnie.
źródło
Moje rozumienie całkowitej różnicy miesięcy między 2 datami ma integralną i ułamkową część (data ma znaczenie).
Integralną częścią jest różnica pełnych miesięcy.
Część ułamkowa jest dla mnie różnicą% dnia (do pełnych dni miesiąca) między miesiącem początkowym a końcowym.
Dzięki temu rozszerzeniu są to wyniki:
źródło
Nie ma na to wielu jasnych odpowiedzi, ponieważ zawsze zakładasz różne rzeczy.
To rozwiązanie oblicza między dwiema datami miesiące między założeniem, że chcesz zapisać dzień miesiąca do porównania (co oznacza, że dzień miesiąca jest uwzględniany w obliczeniach)
Przykład: jeśli masz datę 30 stycznia 2012 r., 29 lutego 2012 r. Nie będzie miesiącem, ale 01 marca 2013 r. Będzie.
Został przetestowany dość dokładnie, prawdopodobnie wyczyści go później, gdy go użyjemy, ale tutaj:
źródło
W oparciu o doskonałą pracę DateTimeSpan wykonaną powyżej, trochę znormalizowałem kod; wydaje się, że działa całkiem dobrze:
źródło
CompareDates(x, y)
gdzie,x={01/02/2019 00:00:00}
ay={01/05/2020 00:00:00}
następnieMonths
daje mi2
Ta prosta funkcja statyczna oblicza ułamek miesięcy między dwoma czasami danych, np
Funkcja zakłada, że pierwsza data jest mniejsza niż druga data. Aby poradzić sobie z ujemnymi przedziałami czasu, można łatwo zmodyfikować funkcję, wprowadzając na początku znak i zmienną zamianę.
źródło
Możliwość obliczenia różnicy między 2 datami w miesiącach jest całkowicie logiczną rzeczą i jest potrzebna w wielu aplikacjach biznesowych. Kilku programistów, którzy dostarczyli komentarze, takie jak - jaka jest różnica w miesiącach między „1 maja 2010 r.” A „16 czerwca 2010 r., Jaka jest różnica w miesiącach od 31 grudnia 2010 r. Do 1 stycznia 2011 r.? podstawy aplikacji biznesowych.
Oto odpowiedź na powyższe 2 komentarze - Liczba miesięcy między 1 maja 2010 r. A 16 czerwca 2010 r. Wynosi 1 miesiąc, liczba miesięcy między 31 grudnia 2010 r. A 1 stycznia 2011 r. Wynosi 0. To głupotą byłoby obliczyć je jako 1,5 miesiąca i 1 sekundę, jak sugerowali powyżsi koderzy.
Ludzie, którzy pracowali nad kartami kredytowymi, przetwarzaniem kredytów hipotecznych, przetwarzaniem podatków, przetwarzaniem czynszu, miesięcznymi obliczeniami odsetek i szeroką gamą innych rozwiązań biznesowych, zgodziliby się.
Problem polega na tym, że taka funkcja nie jest zawarta w C # lub VB.NET. Datediff bierze pod uwagę tylko lata lub składnik miesiąca, więc jest właściwie bezużyteczny.
Oto kilka rzeczywistych przykładów tego, gdzie trzeba i poprawnie można obliczyć miesiące:
Mieszkałeś w krótkoterminowym wynajmie od 18 lutego do 23 sierpnia. Ile miesięcy tam przebywałeś? Odpowiedź jest prosta - 6 miesięcy
Posiadasz rachunek bankowy, w którym naliczane są odsetki na koniec każdego miesiąca. Wpłacasz pieniądze 10 czerwca i wyciągasz je 29 października (tego samego roku). Przez ile miesięcy otrzymujesz odsetki? Bardzo prosta odpowiedź - 4 miesiące (znowu dodatkowe dni nie mają znaczenia)
W aplikacjach biznesowych większość czasu, kiedy trzeba obliczyć miesiące, to dlatego, że trzeba znać „pełne” miesiące na podstawie tego, jak ludzie obliczają czas; nie oparte na abstrakcyjnych / nieistotnych myślach.
źródło
Rozszerzona struktura Kirks z ToString (format) i Duration (długie ms)
źródło
źródło