Мені потрібно знати, чи є дата між DateRange. У мене три побачення:
// The date range
DateTime startDate;
DateTime endDate;
DateTime dateToCheck;
Найпростішим рішенням є порівняння, але чи є розумніший спосіб зробити це?
Мені потрібно знати, чи є дата між DateRange. У мене три побачення:
// The date range
DateTime startDate;
DateTime endDate;
DateTime dateToCheck;
Найпростішим рішенням є порівняння, але чи є розумніший спосіб зробити це?
Відповіді:
Ні, просте порівняння мені здається непоганим:
return dateToCheck >= startDate && dateToCheck < endDate;
Про що слід подумати:
DateTime
є дещо дивним типом з точки зору часових поясів. Це може бути UTC, це може бути "локально", це може бути неоднозначно. Обов’язково порівнюйте яблука з яблуками.DateTime
Важливо переконатися, що порівнювані вами товари однакові (UTC / Local) важливо. З різними видами порівнюватиметься необроблений час замість того, щоб перетворювати обидва на загальний вид.
return startDate <= dateToCheck && dateToCheck < endDate
здається трохи читабельнішим.
Зазвичай для таких речей я створюю реалізацію діапазону Фаулера .
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);
}
}
Використання досить просте:
DateRange range = new DateRange(startDate, endDate);
range.Includes(date)
Ви можете використовувати методи розширення, щоб зробити його трохи читабельнішим:
public static class DateTimeExtensions
{
public static bool InRange(this DateTime dateToCheck, DateTime startDate, DateTime endDate)
{
return dateToCheck >= startDate && dateToCheck < endDate;
}
}
Тепер ви можете написати:
dateToCheck.InRange(startDate, endDate)
IsInRange()
як назву функції
Ви можете використовувати:
return (dateTocheck >= startDate && dateToCheck <= endDate);
Я виявив, що наступна бібліотека є найбільш корисною при будь-якій математиці дати. Я все ще вражений, що нічого подібного не є частиною фреймворку .Net.
http://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET
Слідом за Сергій відповіді , я думаю , що це більш загальний варіант більш відповідно до Фаулером Range
ідеєю, і вирішує деякі з проблем , з цією відповіддю , такими як можливість мати Includes
методи в узагальненому класі шляхом обмеження , T
як IComparable<T>
. Він також незмінний, як те, що ви очікували б від типів, які розширюють функціональність інших типів значень 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;
}