确定时间是否落在指定的小时范围内

时间:2010-12-29 21:05:14

标签: c#

我是C#的新手。我想检查时间是否在2个给定小时之间,如果是,那么就做点什么。谁能举个例子呢?

伪代码示例:

int starthour = 17;
int endhour = 2;

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

如何检查hourstarthour之间是否endhour?在C#中,时间以AM / PM格式返回,因此我不知道它是否会将17数字理解为“下午5点”。

7 个答案:

答案 0 :(得分:16)

假设你在谈论当前的时间,我会做这样的事情:

// 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();
}

在最终条件中调整<=以适合您是否希望边界包含/排除。

如果你在谈论从其他地方指定的时间是否在某个边界内,只需在另一时间更改“现在”。

答案 1 :(得分:3)

实际上,如果我们在这里处理纯粹的时间,比如0到23和0的阿贝尔环,我相信以下实际上是一个有效的解决方案:

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

虽然复杂,但它本质上是一个if-else,你有一个不同的算法,取决于start&lt; = end or not,其中t是你想要测试的时间。在第一种情况下,start和end是正常顺序,因此t必须大于start且小于end。在start大于end的情况下,相反范围之外的时间是我们想要的:

  • NOT(结束&lt; t和t&lt; start)

使用德摩根定理:

  • NOT(结束&lt; t)或NOT(t&lt; start)
  • NOT(t&lt; start)或NOT(end&lt; t)
  • t&gt; =开始或结束&gt; = t
  • start&lt; = t或t&lt; = end

这可以解决你和我的问题。

@JonSkeet

问题是,看看你的算法,让我们暂时假设时间是凌晨1点,第1天。

  • 现在持有第1天凌晨1点
  • 今天是午夜第1天
  • 开始于第1天下午5点举行(原定示例)
  • End持有第1天凌晨2点(再次来自示例)
  • End持有凌晨2点(从开始&gt;结束)

现在,除非我弄错了,现在开始≰从第一天开始是下午5点,现在是凌晨1点,这是现在之前,因此测试失败,但原始问题需要凌晨1点,因为早上1点是下午5点之间凌晨2点。我错过了什么吗?

@布赖恩

此外,查看您的代码,我认为您可以检测到凌晨1点,但现在您的问题会在晚上10点(22:00)发生,因为您的时间已经过去了:

  • Start is 17
  • 结束是26
  • 现在是22 + 24 = 46!所以你会在低于测试中失败。

显然,一般情况非常棘手!当你像我一样被限制在Google Spreadsheets时更是如此。

答案 2 :(得分:2)

当减去DateTime时,您会得到一个TimeSpan结构,您可以查询总小时数(TotalHours属性)等内容:

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

如果您想查看时间是否相同,那么您可以使用TotalMilliseconds - 对于相同的DateTime s,这将等于0。

答案 3 :(得分: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;
        }

答案 4 :(得分: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;
}

答案 5 :(得分: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之间的偏好。

答案 6 :(得分:0)

使用Jon Skeet上面的解决方案,我添加了一个修复,如果开始时间是在开始时间之后,例如,您在晚上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;
        }

    }