Dawood Awan
Dawood Awan

Reputation: 7338

Check if restaurant is open or closed C# with multiple opening/closing times

I have a scenario in which a restaurant can have multiple opening/closing times, and the closing-time can be passed mid-night in some cases.

Something like this:

Day - [Monday] - Open Time - [09:00] - Close Time - [18:00]
Day - [Monday] - Open Time - [22:00] - Close Time - [02:00]

Day - [Tuesday] - Open Time - [12:00] - Close Time - [23:59]

Day - [Wednesday] - Open Time - [09:00] - Close Time - [18:00]
Day - [Wednesday] - Open Time - [22:00] - Close Time - [02:00]

Day - [Thursday] - Open Time - [14:00] - Close Time - [02:00]

Day - [Friday] - Open Time - [16:00] - Close Time - [02:00]

Day - [Saturday] - Open Time - [12:00] - Close Time - [01:00]

Day - [Sunday] - Open Time - [12:00] - Close Time - [01:59]

I need to check if the restaurant is opened or closed at the time of request, this is what I have got so far (Posting entire code with sample data - you can paste in a C# Console App and run it):

internal class Program
{
    private static void Main(string[] args)
    {
        var restaurantList = new RestaurantTimingList();


        Console.WriteLine("---------------------------------RESTAURANT TIMINGS -----------------------------------------");
        Console.WriteLine("---------------------------------------------------- ----------------------------------------");

        foreach (var timing in restaurantList.Timings)
        {
            Console.WriteLine("Day - [{0}] - Open Time - [{1}] - Close Time - [{2}]", timing.Day, timing.OpenTimeString, timing.CloseTimeString);
        }
        Console.WriteLine("---------------------------------------------------- ----------------------------------------");
        Console.WriteLine("---------------------------------------------------- ----------------------------------------");

        var time = "01:01";

        var dayOfWeek = DayOfWeek.Saturday;

        Console.WriteLine("Day - [{0}] - Time - [{1}] - IsOpen - [{2}]", dayOfWeek, time, restaurantList.CheckIsOpen(dayOfWeek, time));
        Console.WriteLine("---------------------------------------------------- ----------------------------------------");

        time = "01:00";
        Console.WriteLine("Day - [{0}] - Time - [{1}] - IsOpen - [{2}]", dayOfWeek, time, restaurantList.CheckIsOpen(dayOfWeek, time));
        Console.WriteLine("---------------------------------------------------- ----------------------------------------");

        dayOfWeek = DayOfWeek.Tuesday;
        time = "00:00";
        Console.WriteLine("Day - [{0}] - Time - [{1}] - IsOpen - [{2}]", dayOfWeek, time, restaurantList.CheckIsOpen(dayOfWeek, time));
        Console.WriteLine("---------------------------------------------------- ----------------------------------------");

        time = "23:58";
        Console.WriteLine("Day - [{0}] - Time - [{1}] - IsOpen - [{2}]", dayOfWeek, time, restaurantList.CheckIsOpen(dayOfWeek, time));
        Console.WriteLine("---------------------------------------------------- ----------------------------------------");

        Console.ReadKey();
    }
}


public class RestaurantTiming
{
    public int TimingId { get; set; }
    public DayOfWeek Day { get; set; }

    public string OpenTimeString { get; set; }
    public TimeSpan OpenTime { get; set; }

    public string CloseTimeString { get; set; }
    public TimeSpan CloseTime { get; set; }

    public RestaurantTiming(int timingId, DayOfWeek day, string openTime, string closeTime)
    {
        TimingId = timingId;
        Day = day;

        OpenTimeString = openTime;
        OpenTime = TimeSpan.Parse(openTime);

        CloseTimeString = closeTime;
        CloseTime = TimeSpan.Parse(closeTime);
    }
}

public class RestaurantTimingList
{
    public List<RestaurantTiming> Timings { get; set; }

    public RestaurantTimingList()
    {
        Timings = new List<RestaurantTiming>();

        Timings.Add(new RestaurantTiming(1, DayOfWeek.Monday, "09:00", "18:00"));
        Timings.Add(new RestaurantTiming(2, DayOfWeek.Monday, "22:00", "02:00"));

        Timings.Add(new RestaurantTiming(3, DayOfWeek.Tuesday, "12:00", "23:59"));

        Timings.Add(new RestaurantTiming(4, DayOfWeek.Wednesday, "09:00", "18:00"));
        Timings.Add(new RestaurantTiming(5, DayOfWeek.Wednesday, "22:00", "02:00"));

        Timings.Add(new RestaurantTiming(6, DayOfWeek.Thursday, "14:00", "02:00"));

        Timings.Add(new RestaurantTiming(7, DayOfWeek.Friday, "16:00", "02:00"));

        Timings.Add(new RestaurantTiming(8, DayOfWeek.Saturday, "12:00", "01:00"));

        Timings.Add(new RestaurantTiming(9, DayOfWeek.Sunday, "12:00", "01:59"));
    }

    public bool CheckIsOpen(DayOfWeek weekDay, string time)
    {
        var timeSpan = TimeSpan.Parse(time);
        // Group By Day Of week - 
        var grouped = Timings.GroupBy(s => s.Day).ToList();

        // Get All timings of the day
        var weekDayTimings = grouped.FirstOrDefault(s => s.Key == weekDay);

        // No Weekday found - Restaurant closed on this return false
        if (weekDayTimings == null) return false;

        // Check passed time to see if is in Any of the timings of that Day
        foreach (var timing in weekDayTimings)
        {
            Console.WriteLine("[{0}] Open [{1}] - Close [{2}] -  ", weekDay, timing.OpenTimeString, timing.CloseTimeString);

            var start = timing.OpenTime;
            var end = timing.CloseTime;
            var now = timeSpan;

            if (start <= end)
            {
                // start and stop times are in the same day
                if (now >= start && now <= end)
                {
                    // current time is between start and stop
                    return true;
                }
            }
            else
            {
                // start and stop times are in different days
                if (now >= start || now <= end)
                {
                    // current time is between start and stop
                    return true;
                }
            }
        }
        return false;
    }

}

The Problem

I am going to try to explain it with an example:

The restaurant is open on Monday from 10:00 PM - 02:00 AM - so the time moves onto the next day - (Which means that the restaurant is open on Tuesday from 00:00 AM - 02:00 AM)

Now let's say a user makes a request on: Tuesday 01:00 AM

Like this:

 dayOfWeek = DayOfWeek.Tuesday; // What will actually be here DateTime.Now.Day;
 time = "01:00";  // What will actually be here: DateTime.Now.TimeOfDay;
 Console.WriteLine("Day - [{0}] - Time - [{1}] - IsOpen - [{2}]", dayOfWeek, time, restaurantList.CheckIsOpen(dayOfWeek, time));

Now this returns FALSE (Restaurant is NOT open) - But because the timing on Monday is till 02:00 AM this should return true.

Upvotes: 1

Views: 1179

Answers (2)

tym32167
tym32167

Reputation: 4881

I changed a little bit your logic.

Let restaurant timing decide when it match to time and when not

public class RestaurantTiming
{
    public int TimingId { get; set; }
    public Interval[] Intervals { get; set;}

    public string OpenTimeString { get; private set; }
    public string CloseTimeString { get; private set; }

    public RestaurantTiming(int timingId, DayOfWeek day, string openTime, string closeTime)
    {
        TimingId = timingId;
        OpenTimeString = openTime;
        CloseTimeString = closeTime;

        var intervals = new List<Interval>();


        var openTimeParsed = TimeSpan.Parse(openTime);      
        var closeTimeParsed = TimeSpan.Parse(closeTime);

        if (closeTimeParsed > openTimeParsed)
        {
            intervals.Add(new Interval() { Day = day, CloseTime = closeTimeParsed, OpenTime = openTimeParsed });
        }
        else
        {
            intervals.Add(new Interval() { Day = day, CloseTime = new TimeSpan(23,59,59), OpenTime = openTimeParsed });
            intervals.Add(new Interval() { Day = NextDayOfWeek(day), CloseTime = closeTimeParsed, OpenTime = new TimeSpan(0,0,0) });
        }       

        Intervals = intervals.ToArray();
    }

    public bool IsMatch(DayOfWeek day, TimeSpan span)
    {
        return Intervals.Any(x=>x.Day == day && x.OpenTime <= span && x.CloseTime >= span);
    }

    public class Interval
    {
        public DayOfWeek Day { get; set; }      
        public TimeSpan OpenTime { get; set; }      
        public TimeSpan CloseTime { get; set; }
    }

    private DayOfWeek NextDayOfWeek(DayOfWeek current)
    {
        return NextDays[current];
    }

    private static Dictionary<DayOfWeek, DayOfWeek> NextDays = new Dictionary<DayOfWeek, DayOfWeek>()
        {
            {DayOfWeek.Sunday, DayOfWeek.Monday},
            { DayOfWeek.Monday, DayOfWeek.Tuesday},
            { DayOfWeek.Tuesday, DayOfWeek.Wednesday},
            { DayOfWeek.Wednesday, DayOfWeek.Thursday},
            { DayOfWeek.Thursday, DayOfWeek.Friday},
            { DayOfWeek.Friday, DayOfWeek.Saturday},
            { DayOfWeek.Saturday, DayOfWeek.Sunday}
        };
}

In that case Timing list will be simpler

public class RestaurantTimingList
{
    public List<RestaurantTiming> Timings { get; set; }

    public RestaurantTimingList()
    {
        Timings = new List<RestaurantTiming>();

        Timings.Add(new RestaurantTiming(1, DayOfWeek.Monday, "09:00", "18:00"));
        Timings.Add(new RestaurantTiming(2, DayOfWeek.Monday, "22:00", "02:00"));

        Timings.Add(new RestaurantTiming(3, DayOfWeek.Tuesday, "12:00", "23:59"));

        Timings.Add(new RestaurantTiming(4, DayOfWeek.Wednesday, "09:00", "18:00"));
        Timings.Add(new RestaurantTiming(5, DayOfWeek.Wednesday, "22:00", "02:00"));

        Timings.Add(new RestaurantTiming(6, DayOfWeek.Thursday, "14:00", "02:00"));

        Timings.Add(new RestaurantTiming(7, DayOfWeek.Friday, "16:00", "02:00"));

        Timings.Add(new RestaurantTiming(8, DayOfWeek.Saturday, "12:00", "01:00"));

        Timings.Add(new RestaurantTiming(9, DayOfWeek.Sunday, "12:00", "01:59"));
    }

    public bool CheckIsOpen(DayOfWeek weekDay, string time)
    {
        return Timings.Any(x=>x.IsMatch(weekDay, TimeSpan.Parse(time)));
    }

}

And we have to apply minimal changes to Main

void Main()
{
    var restaurantList = new RestaurantTimingList();

    Console.WriteLine("---------------------------------RESTAURANT TIMINGS -----------------------------------------");
    Console.WriteLine("---------------------------------------------------- ----------------------------------------");

    foreach (var timing in restaurantList.Timings.SelectMany(x=>x.Intervals))
    {
        Console.WriteLine("Day - [{0}] - Open Time - [{1}] - Close Time - [{2}]", timing.Day, timing.OpenTime, timing.CloseTime);
    }
    Console.WriteLine("---------------------------------------------------- ----------------------------------------");
    Console.WriteLine("---------------------------------------------------- ----------------------------------------");

    var time = "01:01";

    var dayOfWeek = DayOfWeek.Saturday;

    Console.WriteLine("Day - [{0}] - Time - [{1}] - IsOpen - [{2}]", dayOfWeek, time, restaurantList.CheckIsOpen(dayOfWeek, time));
    Console.WriteLine("---------------------------------------------------- ----------------------------------------");

    time = "01:00";
    Console.WriteLine("Day - [{0}] - Time - [{1}] - IsOpen - [{2}]", dayOfWeek, time, restaurantList.CheckIsOpen(dayOfWeek, time));
    Console.WriteLine("---------------------------------------------------- ----------------------------------------");

    dayOfWeek = DayOfWeek.Tuesday;
    time = "00:00";
    Console.WriteLine("Day - [{0}] - Time - [{1}] - IsOpen - [{2}]", dayOfWeek, time, restaurantList.CheckIsOpen(dayOfWeek, time));
    Console.WriteLine("---------------------------------------------------- ----------------------------------------");

    time = "23:58";
    Console.WriteLine("Day - [{0}] - Time - [{1}] - IsOpen - [{2}]", dayOfWeek, time, restaurantList.CheckIsOpen(dayOfWeek, time));
    Console.WriteLine("---------------------------------------------------- ----------------------------------------");

    Console.ReadKey();  
}

And output

---------------------------------RESTAURANT TIMINGS -----------------------------------------
---------------------------------------------------- ----------------------------------------
Day - [Monday] - Open Time - [09:00:00] - Close Time - [18:00:00]
Day - [Monday] - Open Time - [22:00:00] - Close Time - [23:59:59]
Day - [Tuesday] - Open Time - [00:00:00] - Close Time - [02:00:00]
Day - [Tuesday] - Open Time - [12:00:00] - Close Time - [23:59:00]
Day - [Wednesday] - Open Time - [09:00:00] - Close Time - [18:00:00]
Day - [Wednesday] - Open Time - [22:00:00] - Close Time - [23:59:59]
Day - [Thursday] - Open Time - [00:00:00] - Close Time - [02:00:00]
Day - [Thursday] - Open Time - [14:00:00] - Close Time - [23:59:59]
Day - [Friday] - Open Time - [00:00:00] - Close Time - [02:00:00]
Day - [Friday] - Open Time - [16:00:00] - Close Time - [23:59:59]
Day - [Saturday] - Open Time - [00:00:00] - Close Time - [02:00:00]
Day - [Saturday] - Open Time - [12:00:00] - Close Time - [23:59:59]
Day - [Sunday] - Open Time - [00:00:00] - Close Time - [01:00:00]
Day - [Sunday] - Open Time - [12:00:00] - Close Time - [23:59:59]
Day - [Monday] - Open Time - [00:00:00] - Close Time - [01:59:00]
---------------------------------------------------- ----------------------------------------
---------------------------------------------------- ----------------------------------------
Day - [Saturday] - Time - [01:01] - IsOpen - [True]
---------------------------------------------------- ----------------------------------------
Day - [Saturday] - Time - [01:00] - IsOpen - [True]
---------------------------------------------------- ----------------------------------------
Day - [Tuesday] - Time - [00:00] - IsOpen - [True]
---------------------------------------------------- ----------------------------------------
Day - [Tuesday] - Time - [23:58] - IsOpen - [True]
---------------------------------------------------- ----------------------------------------

Edit: I pointed end of day as new TimeSpan(24,59,59), but if it is matter for you to check exactly 00:00, you can replace it with new TimeSpan(24,0,0)

Upvotes: 4

hitesh sharma
hitesh sharma

Reputation: 69

there are two ways to get what you want!

  1. As suggested in comments, you can create a new table (either manually , if allowed, or by code!)that has opening and closing time for every day. hence, if time is 22:00 to 02:00 for Monday, your new table will have 22:00 to 23:59 Monday and 00:00 to 02:00 Tuesday.

This will simplify your problem and give correct output with your code.

  1. If you do not want to go with the above solution, you can do this: check opening and closing times of previous day to see if they are open after midnight as well.

hope this helps! :)

Upvotes: 0

Related Questions