2011-01-24 12 views
54

Muszę wiedzieć, jeśli Data jest między DateRange. Mam trzy daty:Jak sprawdzić, czy DateTime jest między DateRange w C#

// The date range 
DateTime startDate; 
DateTime endDate; 

DateTime dateToCheck; 

Łatwe rozwiązanie polega na porównaniu, ale czy istnieje lepszy sposób na zrobienie tego?

Z góry dziękuję.

+1

Inteligentniejszy sposób sprawdzania, czy data mieści się między tymi datami? –

+2

Co jest więc mądrzejsze niż proste rozwiązanie? – Polyfun

Odpowiedz

89

Nie, wykonując proste porównanie wygląda dobrze do mnie:

return dateToCheck >= startDate && dateToCheck < endDate; 

miejsca myśleć choć:

  • DateTime jest nieco dziwny typ pod względem stref czasowych. Może to być UTC, może być "lokalne", może być niejednoznaczne. Upewnij się, że porównujesz jabłka z jabłkami.
  • Zastanów się, czy Twoje punkty początkowe i końcowe powinny być pełne czy wyłączne. Zrobiłem powyższy kod traktują go jako dolną granicę i wyłączną górną granicę.
+0

Tak. Upewnienie się, że 'DateTime's porównywane są tego samego rodzaju (UTC/Local) jest ważne. W różnych rodzajach czas surowy zostanie porównany zamiast konwersji do wspólnego rodzaju. – CodesInChaos

+4

'return startDate <= dateToCheck && dateToCheck

+4

@MauricioMorales: To zależy; niektórzy ludzie uważają, że łatwiej jest przeczytać "nieco różny" (data do sprawdzenia) po lewej stronie konsekwentnie. Właśnie to robię. Widzę zalety podejścia "w porządku chronologicznym", ale myślę, że osobiście wolałbym sposób, w jaki go otrzymałem. –

7

Można użyć:

return (dateTocheck >= startDate && dateToCheck <= endDate); 
52

Zazwyczaj tworzę Fowler's Range implementację takich rzeczy.

public interface IRange<T> 
{ 
    T Start { get; } 
    T End { get; } 
    bool Includes(T value); 
    bool Includes(IRange<T> range); 
} 

public class DateRange : IRange<DateTime>   
{ 
    public DateRange(DateTime start, DateTime end) 
    { 
     Start = start; 
     End = end; 
    } 

    public DateTime Start { get; private set; } 
    public DateTime End { get; private set; } 

    public bool Includes(DateTime value) 
    { 
     return (Start <= value) && (value <= End); 
    } 

    public bool Includes(IRange<DateTime> range) 
    { 
     return (Start <= range.Start) && (range.End <= End); 
    } 
} 

Użycie jest bardzo proste:

DateRange range = new DateRange(startDate, endDate); 
range.Includes(date) 
+0

Po prostu głupia obserwacja, czy konstruktor nie musi zagwarantować, że start jest mniejszy od końca, a jeśli nie, to złamie logikę ... szczególnie w przypadku Includes (zakres IRange ) –

+0

Człowiek to jest taki dobre rozwiązanie działa nawet z LINQ. Tak jak poniżej: var valueFromVacationsList = vacationBookingsForThisMonth.FirstOrDefault (s => (s.Id == currentUser.Id) && new DateRange (s.StartDateTime, s.EndDateTime).Obejmuje (itemDate)); – Kadaj

29

Można użyć metody rozszerzenie zrobić to trochę bardziej czytelne:

public static class DateTimeExtensions 
{ 
    public static bool InRange(this DateTime dateToCheck, DateTime startDate, DateTime endDate) 
    { 
     return dateToCheck >= startDate && dateToCheck < endDate; 
    } 
} 

Teraz można napisać:

dateToCheck.InRange(startDate, endDate) 
+16

fajne podejście, chociaż użyłbym 'IsInRange()' jako nazwy funkcji – Andrew

Powiązane problemy