web-dev-qa-db-fra.com

Comment savoir si un DateTime est compris entre une plage de dates en C #

J'ai besoin de savoir si une date est comprise entre un DateRange. J'ai trois dates:

// The date range
DateTime startDate;
DateTime endDate;

DateTime dateToCheck;

La solution facile consiste à faire une comparaison, mais existe-t-il un moyen plus intelligent de le faire?

Merci d'avance.

65
Daniel Peñalba

Non, faire une simple comparaison me semble bien:

return dateToCheck >= startDate && dateToCheck < endDate;

Choses à penser cependant:

  • DateTime est un type quelque peu étrange en termes de fuseaux horaires. Ce pourrait être UTC, ça pourrait être "local", ça pourrait être ambigu. Assurez-vous de comparer des pommes avec des pommes, pour ainsi dire.
  • Déterminez si vos points de départ et d'arrivée doivent être inclusifs ou exclusifs. J'ai fait en sorte que le code ci-dessus le traite comme une limite inférieure inclusive et une limite supérieure exclusive.
111
Jon Skeet

Habituellement, je crée implémentation de Fowler's Range pour de telles choses.

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'utilisation est assez simple:

DateRange range = new DateRange(startDate, endDate);
range.Includes(date)
58
Sergey Berezovskiy

Vous pouvez utiliser des méthodes d'extension pour le rendre un peu plus lisible:

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

Maintenant vous pouvez écrire:

dateToCheck.InRange(startDate, endDate)
36
Elian Ebbing

Vous pouvez utiliser:

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

J'ai trouvé que la bibliothèque suivante était la plus utile pour tout type de calcul de date. Je ne suis toujours pas étonné car cela ne fait pas partie du framework .Net.

http://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET

5
landerud

Après réponse de Sergey, je pense que cette version plus générique est plus conforme à l’idée de Range de Fowler et résout certains des problèmes liés à cette réponse, comme le fait de pouvoir avoir le Includes méthodes dans une classe générique en contraignant T comme IComparable<T>. C'est aussi immuable que ce à quoi on pourrait s'attendre avec des types qui étendent les fonctionnalités d'autres types de valeur comme DateTime.

public struct Range<T> where T : IComparable<T>
{
    public Range(T start, T end)
    {
        Start = start;
        End = end;
    }

    public T Start { get; }

    public T End { get; }

    public bool Includes(T value) => Start.CompareTo(value) <= 0 && End.CompareTo(value) >= 0;

    public bool Includes(Range<T> range) => Start.CompareTo(range.Start) <= 0 && End.CompareTo(range.End) >= 0;
}
2
Neo