2015-12-17 1 views
2

Как узнать, действительно ли данный DateTime находится в определенном подмножестве года. В качестве примера я хотел бы узнать, есть ли сегодня между 6 декабря и 2 января. Подмножество выражается как диапазон дат и может «обертываться», как в приведенном примере.Проверьте, соответствует ли данная дата в подмножестве года (например, позднее 6 декабря)

Предположим, UTC, чтобы сбережения на летнее время и т. Д. Не проблема.

Есть ли чистый способ сделать это с помощью .NET BCL?

Дата, которую нужно проверить, и «конечные точки» диапазона дат должны быть произвольными.

+1

Недостаточные требования. Что делать за 29 февраля в качестве даты начала/окончания/проверки? И 6 dec - 2 jan не является «диапазоном года». Он перекрывает 2 года. –

+0

@HenkHolterman это сложнее, чем я думал. Двухлетняя перекрывающаяся часть является преднамеренной. Не уверен, что делать с 29-м, а также с летним сбережением. – boot4life

+1

Обратите внимание, что время тяжелое. http://infiniteundo.com/post/25326999628/falsehoods-programmers-believe-about-time –

ответ

1

Вы явно указываете даты, поэтому я предполагаю, что время не является проблемой, и мы можем игнорировать сложность летнего времени и т. Д. В этом случае вы можете сделать простое числовое выражение даты года и иметь небольшую логику для случаев обертывания. Я не говорю, что это красиво, но он доставляет тебя туда. Например:

void Main() 
{ 
    var range = new DateRange(new DateTime(2015,12,6), new DateTime(2016,1,2)); 

    Console.WriteLine(range.IsDateInRange(new DateTime(2015, 12, 28))); 
    Console.WriteLine(range.IsDateInRange(new DateTime(2015, 1, 1))); 
    Console.WriteLine(range.IsDateInRange(new DateTime(2015, 1, 3))); 
    Console.WriteLine(range.IsDateInRange(new DateTime(2015, 11, 28))); 
} 

public class DateRange 
{ 
    public const int OneYearWrap = 1200; 
    public int BeginValue { get; private set; } 
    public int EndValue { get; private set; } 

    public DateRange(DateTime begin, DateTime end) 
    { 
     BeginValue = DateValue(begin); 
     EndValue = DateValue(end); 
     if (EndValue < BeginValue) 
      EndValue += OneYearWrap; 
    } 

    public bool IsDateInRange(DateTime date) 
    { 
     int dateValue = DateValue(date); 
     if (EndValue > OneYearWrap && dateValue < BeginValue) 
      dateValue += OneYearWrap; 
     return dateValue >= BeginValue && dateValue <= EndValue; 
    } 

    int DateValue(DateTime date) 
    { 
     return date.Month * 100 + date.Day; 
    } 
} 
+0

Это должно сработать. – boot4life

0

Операторы сравнения перегружены для DateTime. Почему бы не использовать что-то вроде:

DateTime x = ... 
if (x > new DateTime(2015, 12, 6)) { 
    // ... do whatever ... 
} 

и оставить грязные детали исполнителям (то есть BCL).

+0

OP уже «может придумать несколько способов сделать это» –

+0

@HenkHolterman: Я не понимаю, что должно быть неэлегантным/неразборчиво об использовании операторов сравнения ...? – Dejan

+1

Как я понял, речь идет о выражении общего диапазона дат в течение любого года, а не конкретных дат. Например. год должен быть исключен из сравнения, которого оператор по умолчанию (к счастью) не делает. – driis

Смежные вопросы