2010-12-29 3 views
3

Я новичок на C#. Я хотел бы проверить, находится ли время между двумя заданными часами, и если да, тогда сделайте что-нибудь. Может ли кто-нибудь дать мне пример?Определите, подходит ли время в указанном диапазоне часов

псевдокод пример:

int starthour = 17; 
int endhour = 2; 

if (hour between starthour and endhour){ 
    dosomething(); 
} 

Как написать проверку ли hour между starthour и endhour? В C# время возвращается в формате AM/PM, поэтому я не знаю, будет ли он понимать номер 17 как «5 PM».

+1

Что вы подразумеваете под «часами между 2-х раз верно»? правда в каком смысле? – hunter

+0

@hunter, я считаю, что мы хотим, чтобы текущее время находилось между двумя указанными временами. Псевдокод говорит: если (час между часом начала и конечным часом) ... – DOK

+0

Я имею в виду, каждый день, когда текущий час> 17 (5 вечера) и час <2 утра, dosomething(). else donothing – Kellyh

ответ

2

При вычитании DateTime с, вы получите TimeSpan структуру, которая вы можете запросить для таких вещей, как общее число часов (TotalHours собственности):

TimeSpan ts = starttime - endtime; 
if(ts.TotalHours > 2) 
{ 
    dosomething(); 
} 

Если вы хотите увидеть, если времена идентичных, то вы можете использовать TotalMilliseconds - для одинаковых DateTime с, это будет равно 0.

+0

Я понимаю, почему вы неправильно поняли, но я уверен, что вопрос заключается в том, как узнать, является ли данный час между двумя другими временами ... – jball

16

Предполагая, что вы говорите о текущей время, я бы SOMET повесят, как это:

// Only take the current time once; otherwise you could get into a mess if it 
// changes day between samples. 
DateTime now = DateTime.Now; 
DateTime today = now.Date; 
DateTime start = today.AddHours(startHour); 
DateTime end = today.AddHours(endHour); 

// Cope with a start hour later than an end hour - we just 
// want to invert the normal result. 
bool invertResult = end < start; 

// Now check for the current time within the time period 
bool inRange = (start <= now && now <= end)^invertResult; 
if (inRange) 
{ 
    DoSomething(); 
} 

Отрегулируйте <= в конечном состоянии удовлетворить, хотите ли вы границы быть включено/эксклюзив.

Если вы говорите о том, находится ли время, указанное в другом месте, в пределах определенной границы, просто измените «сейчас» на другое время.

+0

Выглядит хорошо для меня. Только изменение, которое я сделал бы, это использовать DateTime.Today вместо DateTime.Now.Date. – mikesigs

+3

@whatispunk: Нет, вы не можете этого сделать, потому что вам нужно получить текущее время * ровно один раз * для согласованности. Вам потребуется дата и время позже (окончательное сравнение), поэтому вы не можете использовать 'DateTime.Today'. –

+0

@JonSkeet Я пытаюсь использовать этот фрагмент кода, но в этом случае он не работает: предположим, что время между 8 и 5 утра, и сейчас 4 часа ночи. при сравнении он сегодня использует 8 вечера сегодня и 5 утра, поэтому он исчезает. –

0
bool CheckHour(DateTime check, DateTime start, DateTime end) 
{ 
    if (check.TimeOfDay < start.TimeOfDay) 
     return false; 
    else if (check.TimeOfDay > end.TimeOfDay) 
     return false; 
    else 
     return true; 
} 
0
int starthour = 17; 
int endhour = 2; 
int nowhour = DateTime.Now.Hour; 

if (endhour < starthour) 
{ 
    endhour+=24; 
    nowhour+=24; 
} 

if (starthour <= nowhour && nowhour <= endhour) 
{ 
    dosomething(); 
} 

Я не уверен, я предпочитаю между этим кодом и Jon Skeet's code.

3

На самом деле, если мы снова имеем дело с чисто часов здесь как абелевой кольцо от 0 до 23 и 0, я считаю следующее фактически рабочий раствор:

(start <= end && start <= t && t <= end) or (start > end && (start <= t || t <= end))

комплекс, хотя это , это, по сути, if-else, где у вас есть другой алгоритм в зависимости от того, начинается ли < = конец или нет, где t - это время, которое вы хотите проверить. В первом случае начало и конец - это нормальный порядок, поэтому t должен быть как больше, чем начальный, так и меньше, чем конец.В том случае, когда начало больше, чем конец, время за пределами противоположного диапазона, что мы хотим:

  • НЕ (конец < т и т < начало)

Используя теорему де Моргана:

  • НЕ (конец < т) или нет (т < старт)
  • НЕ (т < старт) или нет (конец < т)
  • т> = начало или конец> = т
  • начало < = т или т = < конец

Это должно решить ваши и мои проблемы.

@JonSkeet

Дело в том, глядя на ваш алгоритм, давайте предположим, что на данный момент времени 1 утра, день 1.

  • теперь держит день 1 утра 1
  • Сегодня проводит день в полночь 1
  • Start имеет 5 вечера День 1 (учитывая оригинальный пример)
  • End имеет 2Ат День 1 (опять же из примера)
  • Конец держит 2Ат День 2 (с момента запуска> конец)

Теперь, если я не ошибаюсь, начать ≰ сейчас, так как старт 5 вечера День 1 и теперь 1 утра День 1, который до сих пор, поэтому тест не пройден но исходный вопрос хотел 1am, включенный в диапазон с 1 утра, между 5:00 и 2:00. Я что-то пропустил?

@ Брайан

Кроме того, глядя на свой код, я думаю, что вы можете обнаружить 1Am но теперь вы имеете проблему с 10pm (22:00), так как ваше время стать:

  • Start is 17
  • Конец составляет 26
  • Сейчас 22 + 24 = 46! так что вы потерпите неудачу при тестировании менее.

Очевидно, что общий случай очень сложный! Более того, когда вы ограничены таблицами Google, как и я.

+0

Потому что это не комментарий, Джон и Брайан никогда не получат уведомление о вашем сообщении здесь. Когда вы заработаете достаточно репутации для публикации комментариев, вы должны начать использовать комментарии для такого рода вещей. –

+0

Спасибо Харви; как вы можете видеть, у меня нет достаточной репутации для комментариев, и я бы хотел, чтобы я мог, потому что я уверен, что моя точка верна; Я, однако, добавил решение, которое, как я считаю, работает для всех случаев, поэтому, пожалуйста, рассмотрите вопрос, который официально официально получил еще раз. Благодаря! – TimeHorse

+0

Dang it, у меня был правильный ответ больше года, и кто-то, кто мог комментировать, сообщил верхний ответ того, что я только что прописал, и теперь верхний плакат прав, и для меня нет никакого кредита. Дай это. – TimeHorse

1

Если вы хотите сравнить минуты, также как и я, вы можете использовать этот фрагмент кода в java.

 //Initialize now, sleepStart, and sleepEnd Calendars 
     Calendar now = Calendar.getInstance(); 
     Calendar sleepStart = Calendar.getInstance(); 
     Calendar sleepEnd = Calendar.getInstance(); 

     //Assign start and end calendars to user specified star and end times 
     long startSleep = settings.getLong("startTime", 0); 
     long endSleep = settings.getLong("endTime", 0); 
     sleepStart.setTimeInMillis(startSleep); 
     sleepEnd.setTimeInMillis(endSleep); 

     //Extract hours and minutes from times 
     int endHour = sleepEnd.get(Calendar.HOUR_OF_DAY); 
     int startHour = sleepStart.get(Calendar.HOUR_OF_DAY); 
     int nowHour = now.get(Calendar.HOUR_OF_DAY); 
     int endMinute = sleepEnd.get(Calendar.MINUTE); 
     int startMinute = sleepStart.get(Calendar.MINUTE); 
     int nowMinute = now.get(Calendar.MINUTE); 

     //get our times in all minutes 
     int endTime = (endHour * 60) + endMinute; 
     int startTime = (startHour * 60) + startMinute; 
     int nowTime = (nowHour * 60) + nowMinute; 

    /*****************What makes this 100% effective***************************/ 
     //Test if end endtime is the next day 
     if(endTime < startTime){ 
      if(nowTime > 0 && nowTime < endTime) 
       nowTime += 1440; 
      endTime += 1440; 
     } 
    /**************************************************************************/ 

     //nowTime in range? 
     boolean inRange = (startTime <= nowTime && nowTime <= endTime); 

     //in range so calculate time from now until end 
     if(inRange){ 
      int timeDifference = (endTime - nowTime); 
      now.setTimeInMillis(0); 
      now.add(Calendar.MINUTE, timeDifference); 
      sleepInterval = now.getTimeInMillis()/1000; 
      editor.putBoolean("isSleeping", true); 
      editor.commit(); 
      Log.i(TAG, "Sleep Mode Detected"); 
      returned = true; 
     } 
0

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

if (stopHour < startHour) 
{ 
end = today.AddHours(stopHour+24); 
} 

Полный код ниже.

private static bool IsInRunHours() 
{ 
     try 
     { 
      ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).Save(ConfigurationSaveMode.Modified); 
      ConfigurationManager.RefreshSection("appSettings"); 
      // after = 18 before = 5 

      // Only take the current time once; otherwise you could get into a mess if it 
      // changes day between samples. 
      DateTime now = DateTime.Now; 
      DateTime today = now.Date; 

      Int32 startHour = ConfigurationManager.AppSettings["UpdateRunAfter"].ToInt(); 
      Int32 stopHour = ConfigurationManager.AppSettings["UpdateRunBefore"].ToInt(); 


      DateTime start = today.AddHours(startHour); 
      DateTime end = today.AddHours(stopHour); 

      if (stopHour < startHour) 
      { 
       end = today.AddHours(stopHour+24); 

      } 


      //ConfigurationManager.AppSettings["UpdateRunBefore"].ToInt() 
      //ConfigurationManager.AppSettings["UpdateRunAfter"].ToInt() 
      // Cope with a start hour later than an end hour - we just 
      // want to invert the normal result. 
      bool invertResult = end < start; 

      // Now check for the current time within the time period 
      bool inRange = (start <= now && now <= end)^invertResult; 
      if (inRange) 
      { 
       return true; 
      } 
      else 
      { 
       return false; 
      } 



     } 
     catch 
     { 
      return false; 
     } 

    }