2011-01-24 5 views
54

Ho bisogno di sapere se una Data è tra un DateRange. Ho tre date:Come sapere se un DateTime è tra un DateRange in C#

// The date range 
DateTime startDate; 
DateTime endDate; 

DateTime dateToCheck; 

La soluzione semplice sta facendo un confronto, ma c'è un modo più intelligente per fare questo?

Grazie in anticipo.

+1

Un modo più intelligente allora solo controllando se la data è compresa tra quelle date? –

+2

Quindi cos'è più intelligente di una soluzione facile? – Polyfun

risposta

89

No, fare un semplice confronto sembra buono per me:

return dateToCheck >= startDate && dateToCheck < endDate; 

cose a cui pensare però:

  • DateTime è un tipo un po 'strano in termini di fusi orari. Potrebbe essere UTC, potrebbe essere "locale", potrebbe essere ambiguo. Assicurati di confrontare le mele con le mele, per così dire.
  • Considerare se i punti di partenza e di arrivo dovrebbero essere inclusivi o esclusivi. Ho reso il codice sopra trattato come un limite inferiore inclusivo e un limite superiore esclusivo.
+0

Sì. Assicurati che il 'DateTime' che confronti sia dello stesso tipo (UTC/Locale) sia importante. Con tipi diversi il tempo grezzo verrà confrontato invece di convertire entrambi in un tipo comune. – CodesInChaos

+4

'return startDate <= dateToCheck && dateToCheck

+4

@MauricioMorales: dipende; alcune persone trovano più facile leggere "il bit che sta variando" (la data da verificare) essendo costantemente sul lato sinistro. Questo è quello che tendo a fare. Vedo anche i vantaggi dell'approccio "in ordine cronologico", ma penso che preferirei personalmente il modo in cui l'ho ottenuto. –

7

È possibile utilizzare:

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

solito creare Fowler's Range implementazione per queste cose.

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); 
    } 
} 

L'uso è piuttosto semplice:

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

Solo un'osservazione stupida, il costruttore non ha bisogno di garantire che l'avvio sia inferiore alla fine, in caso contrario, interromperà la logica ... specialmente sul Comprende (intervallo IRange ) –

+0

Man è un tale buona soluzione funziona anche con LINQ. In questo modo: var valueFromVacationsList = vacationBookingsForThisMonth.FirstOrDefault (s => (s.Id == currentUser.Id) && new DateRange (s.StartDateTime, s.EndDateTime).Include (itemDate)); Metodo – Kadaj

29

è possibile utilizzare metodi di estensione per renderlo un po 'più leggibile:

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

Ora si può scrivere:

dateToCheck.InRange(startDate, endDate) 
+16

, anche se userei 'IsInRange()' come nome della funzione – Andrew

Problemi correlati