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.
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.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)
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)
Vous pouvez utiliser:
return (dateTocheck >= startDate && dateToCheck <= endDate);
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
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;
}