2011-01-24 12 views
54

Necesito saber si una Fecha se encuentra entre un DateRange. Tengo tres fechas:Cómo saber si un DateTime está entre un DateRange en C#

// The date range 
DateTime startDate; 
DateTime endDate; 

DateTime dateToCheck; 

La solución fácil está haciendo una comparación, pero hay una manera más inteligente para hacer esto?

Gracias de antemano.

+1

Una forma más inteligente a continuación, simplemente comprobar si la fecha es entre esas fechas? –

+2

Entonces, ¿qué es más inteligente que una solución fácil? – Polyfun

Respuesta

89

No, haciendo una simple comparación se ve bien para mí:

return dateToCheck >= startDate && dateToCheck < endDate; 

cosas en que pensar sin embargo:

  • DateTime es un tipo algo extraño en términos de zonas horarias. Podría ser UTC, podría ser "local", podría ser ambiguo. Asegúrate de que estás comparando manzanas con manzanas, por así decirlo.
  • Considere si sus puntos de inicio y fin deben ser inclusivos o exclusivos. He hecho que el código anterior lo trate como un límite inferior inclusivo y un límite superior exclusivo.
+0

Sí. Asegurarse de que el 'DateTime's que compara son del mismo tipo (UTC/Local) es importante. Con diferentes tipos, se comparará el tiempo en bruto en lugar de convertir ambos a un tipo común. – CodesInChaos

+4

'return startDate <= dateToCheck && dateToCheck

+4

@MauricioMorales: depende; a algunas personas les resulta más fácil leer "el bit que varía" (la fecha para verificar) estando en el lado izquierdo de forma consistente. Eso es lo que tiendo a hacer. También veo las ventajas del enfoque "en orden cronológico", pero creo que personalmente prefiero la forma en que lo tengo. –

7

Se puede utilizar:

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

Por lo general crean Fowler's Range aplicación para este tipo de cosas.

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

El uso es bastante simple:

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

Solo una observación tonta, el constructor no necesita asegurarse de que el inicio sea menor que el final, si no lo hace, rompería la lógica ... especialmente en el rango de Inclusiones (IRange ) –

+0

Hombre esto es tal buena solución, incluso funciona con LINQ. De la misma manera: var valueFromVacationsList = vacationBookingsForThisMonth.FirstOrDefault (s => (s.Id == currentUser.Id) && DateRange (s.StartDateTime, s.EndDateTime).Incluye (itemDate); – Kadaj

29

usted podría utilizar métodos de extensión para que sea un poco más fácil de leer:

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

Ahora se puede escribir:

dateToCheck.InRange(startDate, endDate) 
+16

buen enfoque, aunque usaría 'IsInRange()' como el nombre de la función – Andrew

Cuestiones relacionadas