简体   繁体   English

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

[英]Determine if time falls in designated hour range

I am new at C#. 我是C#的新手。 I'd like to check whether a time is between 2 given hours, and if so then do something. 我想检查时间是否在2个给定小时之间,如果是,那么就做点什么。 Can anyone give me an example? 谁能举个例子?

pseudocode example: 伪代码示例:

int starthour = 17;
int endhour = 2;

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

How do I write a check on whether hour is between starthour and endhour ? 如何检查hour是否在starthourendhour hour之间? In C#, the time is returned in AM/PM format so I don't know if it will understand the 17 number as "5 PM". 在C#中,时间以AM / PM格式返回,因此我不知道它是否会将17号码理解为“5 PM”。

Assuming you're talking about the current time, I'd do something like this: 假设你在谈论当前时间,我会做这样的事情:

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

Adjust the <= in the final condition to suit whether you want the boundaries to be inclusive/exclusive. 在最终条件下调整<=以适合您是否希望边界包含/排除。

If you're talking about whether a time specified from elsewhere is within a certain boundary, just change "now" for the other time. 如果您在谈论从其他地方指定的时间是否在某个边界内,则只需在另一时间更改“现在”。

Actually, if we're dealing with pure hours here like a Abelian Ring from 0 to 23 and 0 again, I believe the following is actually a working solution: 实际上,如果我们在这里处理纯粹的时间,比如0到23和0的阿贝尔环,我相信以下实际上是一个有效的解决方案:

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

Complex though this is, it is essentially an if-else where you have a different algorithm depending on whether start <= end or not, where t is the time you wish to test. 虽然复杂,但它本质上是一个if-else,你有一个不同的算法,取决于start <=是否,其中t是你想要测试的时间。 In the first case, start and end are normal order, so t must be both greater than start and less than end. 在第一种情况下,start和end是正常顺序,因此t必须大于start且小于end。 In the case where start is greater than end, the times outside the opposite range are what we want: 在start大于end的情况下,相反范围之外的时间是我们想要的:

  • NOT(end < t and t < start) NOT(结束<t和t <开始)

Using DeMorgan's theorem: 使用德摩根定理:

  • NOT(end < t) or NOT(t < start) NOT(结束<t)或NOT(t <开始)
  • NOT(t < start) or NOT(end < t) NOT(t <start)或NOT(end <t)
  • t >= start or end >= t t> =开始或结束> = t
  • start <= t or t <= end 开始<= t或t <=结束

This should solve your and my problems. 这应该解决你和我的问题。

@JonSkeet @JonSkeet

The thing is, looking at your algorithm, let's assume for a moment the time is 1am, day 1. 问题是,看看你的算法,让我们暂时假设时间是凌晨1点,第1天。

  • Now holds 1am Day 1 现在凌晨1点举行
  • Today holds midnight Day 1 今天是午夜第1天
  • Start holds 5pm Day 1 (given the original example) 开始在第1天下午5点举行(给出原始示例)
  • End holds 2am Day 1 (again from the example) 结束时间为凌晨2点(再次来自示例)
  • End holds 2am Day 2 (since start > end) 结束时间为凌晨2点(从开始>结束)

Now, unless I'm mistaken, start ≰ now since start is 5pm Day 1 and now is 1am Day 1 which is before now, therefore the test fails but the original question wanted 1am included in the range since 1am is between 5pm and 2am. 现在,除非我弄错了,现在开始≰现在从第1天开始是下午5点,现在是第1天,也就是现在之前的第1天,因此测试失败,但原始问题需要凌晨1点,因为凌晨1点是凌晨5点到凌晨2点。 Did I miss something? 我错过了什么?

@Brian @布赖恩

Also, looking at your code, I think you can detect 1am but now you would have a problem with 10pm (22:00) since your times become: 此外,看看你的代码,我认为你可以检测到凌晨1点,但现在你会遇到问题,因为你的时间变成了下午10点(22:00):

  • Start is 17 开始时间是17
  • End is 26 结束是26
  • Now is 22 + 24 = 46! 现在是22 + 24 = 46! so you will fail in the less-than test. 所以你会在低于测试中失败。

Clearly, the general case is very tricky! 显然,一般情况非常棘手! More so when you're restricted to Google Spreadsheets as I am. 当你像我一样被限制在Google Spreadsheets时更是如此。

When subtracting DateTime s, you get a TimeSpan struct that you can query for things like the total number of hours (the TotalHours property): 当减去DateTime ,你会得到一个TimeSpan结构,你可以查询总小时数( TotalHours属性):

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

If you want to see if the times are identical , then you can use TotalMilliseconds - for identical DateTime s, this will be equal to 0. 如果要查看时间是否相同 ,则可以使用TotalMilliseconds - 对于相同的DateTime ,它将等于0。

If you want to compare minutes also like I do you can use this snippet of code in java. 如果你想像我一样比较分钟,你可以在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;
        }

Using Jon Skeet's solution above I added a fix where if start time is after beginning time eg You start the job after 6pm at night and end it the next morning at 5am. 使用Jon Skeet上面的解决方案,我添加了一个修复,如果开始时间是在开始时间之后,例如,您在晚上6点之后开始工作,并在第二天早上5点结束。 then you need to check this and apply another day to the end time. 然后你需要检查这个并在结束时间再应用一天。 Hope it helps, I personally have spent too much time on this piece of work. 希望它有所帮助,我个人花了太多时间在这项工作上。 have a great day :) 祝你有美好的一天 :)

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

Full Code is below. 完整代码如下。

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;
        }

    }
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;
}
int starthour = 17;
int endhour = 2;
int nowhour = DateTime.Now.Hour;

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

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

I'm not sure which I prefer between this code and Jon Skeet's code . 我不确定这个代码和Jon Skeet的代码之间我更喜欢哪个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM