Niels
Niels

Reputation: 2596

How to check if DateTime.Now is between two given DateTimes for time part only?

For my app I need to know if Now() is between two values.

The user can set a start- and an end-time so he will not disturbed by a notification (during the night for example).

So if have got two TimePickers (start- and end-time) that the user can set.

Lets say the user sets 22:00 for the StartTime and 07:00 for the EndTime (this would cover the night).

How can I check if the DateTime.Now is between the selected Start and End time?

EDIT: I only want this to work with the Hour and minutes part. So if the user sets the Start and End time this should work for every night.

Upvotes: 50

Views: 106900

Answers (10)

I just find it more clear and reuseable to make an extension method.

somewhere in your code:

public static partial class Extensions
{
    public static bool Between(this DateTime dateTime, DateTime from, DateTime to)
    {
        if (from < to)
            return dateTime >= from && dateTime <= to;
        return dateTime <= from && dateTime >= to;
    }
}

usage:

var from = DateTime.Now.AddHours(-1);
var to = DateTime.Now.AddHours(1);
var result1 = DateTime.Now.Between(from, to); // true
var result2 = DateTime.Now.Between(from, from); // false

Upvotes: 0

Andre M
Andre M

Reputation: 81

One liner:

var isBetweenTwoTimes = TimeOnly.FromDateTime(DateTime.UtcNow).IsBetween(new TimeOnly(04, 00), new TimeOnly(10, 00));

Upvotes: 0

Farshad Davoudi
Farshad Davoudi

Reputation: 111

Update 02-June-2023:

There is an easier new way to accomplish it using the TimeOnly struct type introduced in .NET 6.

var nowTimeOnly = TimeOnly.FromDateTime(DateTime.Now);
var startTimeOnly = new TimeOnly(startTimeHour, startTimeMinute);
var endTimeOnly = new TimeOnly(endTimeHour, endTimeMinute);

if (nowTimeOnly.IsBetween(startTimeOnly, endTimeOnly))
{
}

The IsBetween method is a built-in method

Determines if a time falls within the range provided. Supports both "normal" ranges such as 10:00-12:00, and ranges that span midnight such as 23:00-01:00.

Hope this can help someone.

Upvotes: 2

yhw42
yhw42

Reputation: 3434

Since you are only gathering two times without dates, you need to figure out if the two times are from the same day or not. If you put the StartTime, EndTime, and Now into TimeSpans:

if (StartTime > EndTime) 
{
    // the range crosses midnight, do the comparisons independently
    return (StartTime < Now) || (Now < EndTime);
}
else 
{
    // the range is on the same day, both comparisons must be true
    return StartTime < Now && Now < EndTime;
}

Upvotes: 10

Paul Fleming
Paul Fleming

Reputation: 24526

DateTime nowDate = DateTime.Now;
// set these to today + time from time picker
DateTime startDate = new DateTime(nowDate.Year, nowDate.Month, nowDate.Day,
    selectedStart.Hour, selectedStart.Minute, 0);
DateTime endDate = new DateTime(nowDate.Year, nowDate.Month, nowDate.Day, 
    selectedEnd.Hour, selectedEnd.Minute, 0);
bool isBetween = nowDate < endDate && nowDate > startDate;

Update 08-Jun-2016
Not sure why the downvote was appropriate as this is a working solution. The OP did ask specifically for DateTime, however I do recommend using TimeSpan instead as per the answer by @Gabe.

Here's a working function as per my answer:

public static bool TimeBetween(DateTime check, DateTime start, DateTime end, bool inclusive = true)
{
    var from = new DateTime(check.Year, check.Month, check.Day, 
        start.Hour, start.Minute, start.Second, start.Millisecond);
    var to = new DateTime(check.Year, check.Month, check.Day, 
        end.Hour, end.Minute, end.Second, end.Millisecond);

    if (inclusive)
        return from <= check && to >= check;

    return from < check && to > check;
}

Here's a working fiddle: https://dotnetfiddle.net/vZCXqv.

Full code:

using System;

public class Program
{
    public static void Main()
    {
        var start = new DateTime(1, 1, 1, 9, 0, 0);
        var end = new DateTime(1, 1, 1, 17, 0, 0);

        Console.WriteLine("{0} - Too early",                TimeBetween(new DateTime(2014, 1, 1, 08, 59, 59, 999), start, end));
        Console.WriteLine("{0} - On start time exclusive",  TimeBetween(new DateTime(2014, 1, 1, 09, 00, 00, 000), start, end, false));
        Console.WriteLine("{0} - On start time inclusive",  TimeBetween(new DateTime(2014, 1, 1, 09, 00, 00, 000), start, end));
        Console.WriteLine("{0} - After start time",         TimeBetween(new DateTime(2014, 1, 1, 09, 00, 00, 001), start, end));        
        Console.WriteLine("{0} - Before end time",          TimeBetween(new DateTime(2014, 1, 1, 16, 59, 59, 999), start, end));
        Console.WriteLine("{0} - On end time inclusive",    TimeBetween(new DateTime(2014, 1, 1, 17, 00, 00, 000), start, end));
        Console.WriteLine("{0} - On end time exclusive",    TimeBetween(new DateTime(2014, 1, 1, 17, 00, 00, 000), start, end, false));
        Console.WriteLine("{0} - Too late",                 TimeBetween(new DateTime(2014, 1, 1, 17, 00, 00, 001), start, end));
    }

    public static bool TimeBetween(DateTime check, DateTime start, DateTime end, bool inclusive = true)
    {
        var from = new DateTime(check.Year, check.Month, check.Day, start.Hour, start.Minute, start.Second, start.Millisecond);
        var to = new DateTime(check.Year, check.Month, check.Day, end.Hour, end.Minute, end.Second, end.Millisecond);

        if (inclusive)
            return from <= check && to >= check;

        return from < check && to > check;
    }
}

Upvotes: 3

Suplanus
Suplanus

Reputation: 1601

I use this, so you can pass DateTime directly:

        public static bool TimeBetween(DateTime time, DateTime startDateTime, DateTime endDateTime)
    {
        // get TimeSpan
        TimeSpan start = new TimeSpan(startDateTime.Hour, startDateTime.Minute, 0);
        TimeSpan end = new TimeSpan(endDateTime.Hour, endDateTime.Minute, 0);

        // convert datetime to a TimeSpan
        TimeSpan now = time.TimeOfDay;
        // see if start comes before end
        if (start < end)
            return start <= now && now <= end;
        // start is after end, so do the inverse comparison
        return !(end < now && now < start);
    }

Upvotes: 1

Rohit Sachan
Rohit Sachan

Reputation: 1222

    public static bool isCurrenctDateBetween(DateTime fromDate, DateTime toDate)
    {
        DateTime curent = DateTime.Now.Date;
        if (fromDate.CompareTo(toDate) >= 1)
        {
            MessageBox.Show("From Date shouldn't be grater than To Date", "DateRange",MessageBoxButton.OKCancel, MessageBoxImage.Warning);
        }
        int cd_fd = curent.CompareTo(fromDate);
        int cd_td = curent.CompareTo(toDate);

        if (cd_fd == 0 || cd_td == 0)
        {
            return true;
        }

        if (cd_fd >= 1 && cd_td <= -1)
        {
            return true;
        }
        return false;
    }

Upvotes: 3

Gabe
Gabe

Reputation: 86718

First you need to convert everything to the same units (we'll use TimeSpan), then you need to see whether the start-end times cross midnight, and finally do your comparison based on the results of that check:

// convert everything to TimeSpan
TimeSpan start = new TimeSpan(22, 0, 0);
TimeSpan end = new TimeSpan(07, 0, 0);
TimeSpan now = DateTime.Now.TimeOfDay;
// see if start comes before end
if (start < end)
    return start <= now && now <= end;
// start is after end, so do the inverse comparison
return !(end < now && now < start);

Here's a function to do it for you:

bool TimeBetween(DateTime datetime, TimeSpan start, TimeSpan end)
{
    // convert datetime to a TimeSpan
    TimeSpan now = datetime.TimeOfDay;
    // see if start comes before end
    if (start < end)
        return start <= now && now <= end;
    // start is after end, so do the inverse comparison
    return !(end < now && now < start);
}

You would call it like:

bool silenceAlarm = TimeBetween(DateTime.Now, StartTime.Value, EndTime.Value);

Upvotes: 101

iefpw
iefpw

Reputation: 7042

Just do straight comparison.

if(date > startdate && date < enddate)

Upvotes: 1

Stan
Stan

Reputation: 26501

Dupe of Find if current time falls in a time range

DateTime start = new DateTime(2009, 12, 9, 10, 0, 0));
DateTime end = new DateTime(2009, 12, 10, 12, 0, 0));
DateTime now = DateTime.Now;

if ((now > start) && (now < end))
{
   //match found
}

Timespan, again, taken from dupe.

TimeSpan start = new TimeSpan(10, 0, 0);
TimeSpan end = new TimeSpan(12, 0, 0);
TimeSpan now = DateTime.Now.TimeOfDay;

if ((now > start) && (now < end))
{
   //match found
}

Upvotes: 1

Related Questions