2013-09-30 4 views
1

Я знаю, что этот вопрос задан много раз, но у меня небольшой поворот. Есть много разных сдвигов на работе, и у меня есть две строки shiftStart и shiftEnd. (пример "18:00:00 PM" & "03:00:00 AM" соответственно). Это составляет полдень к утру. Я пытаюсь сделать функцию, которая говорит мне, если DateTime.Now находится в пределах этого временного периода.Текущее время в диапазоне

Примечание:сдвиг может быть что-нибудь ... утром до полудня, в полдень до утра, не фиксированной длительности (например, 8 часов).

static bool NowWithinShiftTime("6:00:00 PM", "03:00:00 AM") 

Ниже то, что я пытался, но независимо от того, что я делаю, я не могу найти логику ... Пожалуйста, помогите мне ...

static bool NowWithinShiftTime(string shiftStart, string shiftEnd) 
    { 
     DateTime startDate; 
     DateTime endDate; 
     DateTime now = DateTime.Now; 

     TimeSpan startTime = DateTime.Parse(shiftStart).TimeOfDay; 
     TimeSpan endTime = DateTime.Parse(shiftEnd).TimeOfDay; 

     if (startTime < endTime) // same day 
     { 
      startDate = new DateTime(now.Year, now.Month, now.Day) + startTime; 
      endDate = new DateTime(now.Year, now.Month, now.Day) + endTime; 
     } 
     else // next day 
     { 
      startDate = new DateTime(now.Year, now.Month, now.AddDays(-1).Hour) + startTime; 
      endDate = DateTime.Today.AddDays(1) + endTime; 
     } 
     if (now >= startDate && now <= endDate) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
+0

'now.AddDays (1) .Hour '<- Что? Зачем вам это делать? – Katniss

+0

@ 666bytes: Вы должны предпочесть 'startDate = DateTime.Today + startTime', намного короче и понятнее. На завтра, 'AddDays (1)' как обычно. – Jon

ответ

6

Вы можете придерживаться TimeSpan:

static bool NowWithinShiftTime(string shiftStart, string shiftEnd) 
{ 
    TimeSpan startTime = DateTime.Parse(shiftStart).TimeOfDay; 
    TimeSpan endTime = DateTime.Parse(shiftEnd).TimeOfDay; 
    TimeSpan now = DateTime.Now.TimeOfDay; 

    if (startTime < endTime) 
     return now >= startTime && now <= endTime; 
    else 
     return now >= startTime || now <= endTime; 
} 
+0

@ChrisWue: Ты прав. Теперь исправлено. – Douglas

+1

@ 666bytes Если возможно, было бы даже лучше, если бы функция принимала TimeSpan вместо строк вместо того, чтобы выполнять синтаксический анализ. –

+0

@DouglasThanks мой друг. Действительно оцените ... –

1

Я считаю, что вы 90% там:

static bool NowWithinShiftTime(string shiftStart, string shiftEnd) 
{ 
    DateTime startDate; 
    DateTime endDate; 
    DateTime now = DateTime.Now; 

    TimeSpan startTime = DateTime.Parse(shiftStart).TimeOfDay; 
    TimeSpan endTime = DateTime.Parse(shiftEnd).TimeOfDay; 

    if (startTime < endTime) // same day 
    { 
     startDate = DateTime.Today + startTime; 
     endDate = DateTime.Today + endTime; 
    } 
    else // next day 
    { 
     startDate = DateTime.Today + startTime; 
     endDate = DateTime.Today.AddDays(1) + endTime; 
    } 
    if (now >= startDate && now <= endDate) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

Вот ideone, чтобы показать, что это работает: http://ideone.com/rdb867

+0

Это не сработает, так как по достижении 12:00:00 утра startDate также станет следующей датой. –

+0

В 12:00 утра изменяется дата, поэтому это не проблема. –

+0

Я подделал этот пример * крошечный * бит и получил то, что мне нужно! БЛАГОДАРЯ!! –

6

Во-первых, сделать все бизнес-логика дело только что со временем, связанные с типами. (Лично я бы использовал свою библиотеку Noda Time со своим типом LocalTime для этой работы, но ...) Синтаксический анализ может поступать в код вызова.

Логика достаточно проста: если «время окончания» на самом деле до «начального времени», просто переключите два раунда и инвертируйте результат. В конце концов, вы просто делите день на «время переключения» и «не сдвигаете время» ... и сдвиг (скажем) с 8 вечера до 3 утра «включен», когда сдвиг с 3 до 8 вечера «выключен».

Например:

public bool NowWithinShiftTime(TimeSpan startTimeOfDay, TimeSpan endTimeOfDay) 
{ 
    if (startTimeOfDay > endTimeOfDay) 
    { 
     return !NowWithinShiftTime(endTimeOfDay, startTimeOfDay); 
    } 
    TimeSpan now = DateTime.Now.TimeOfDay; 
    return startTimeOfDay <= now && now < endTimeOfDay; 
} 

Примечания:

  • Я сделал это намеренно полузакрытыми, как правило, подходит для интервалов, так что если вы примыкающие интервалы, любой значение падает ровно в один. Проверьте, что именно вы хотите, хотя это будет иметь значение только для этих двух точных точек в день.
  • Код в настоящее время трудно проверить: я бы посоветовал вам абстрагировать идею «часов» в интерфейс, поэтому вы можете использовать поддельные часы для тестирования. (Нод время делает это для вас, и обеспечивает соответствующий FakeClock.)
+0

Это было приятно ... –

0

Это должно работать:

bool IsWithinTimeRange(DateTime dateToCompare, DateTime startDate, DateTime endDate) 
{ 
    TimeSpan timeToCompare = dateToCompare.TimeOfDay; 
    TimeSpan start = startDate.TimeOfDay; 
    TimeSpan end = endDate.TimeOfDay; 

    if (start < end) 
     return timeToCompare >= start && timeToCompare <= end; 
    else 
     return !(end < timeToCompare && timeToCompare < start); 
} 
1

Это должно работать

static bool NowWithinShiftTime(string shiftStart, string shiftEnd) 
{ 
    DateTime now = DateTime.Now; 
    DateTime startDate = DateTime.Parse(shiftStart); 
    DateTime endDate = DateTime.Parse(shiftEnd); 

    if (endDate < startDate) 
    { 
     endDate = endDate.AddDays(1); 
    } 

    return now >= startDate && now <= endDate; 
} 
+0

Это не так. 'shiftStart' и' shiftEnd' не имеют информации о дате, поэтому 'now' всегда больше, чем' endDate'. – recursive

+0

@recursive Вы уверены? Если дата не указана при анализе текущей даты, применяется –

+0

@recursive I, она работает отлично. Можете ли вы показать какой-либо тестовый пример, где он терпит неудачу? –

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