I have a small file that compares the time and runs a routine based on the result.

    DateTime now = DateTime.Now; //get the current time
    //The DateTime constructor goes (YYYY, MM, DD, HH, MM, SS)
    DateTime start = new DateTime(now.Year, now.Month, now.Day, 00, 00, 00);
    DateTime end = new DateTime(now.Year, now.Month, now.Day, 17, 25, 00);

    while (now.CompareTo(start) >= 0 && now.CompareTo(end) <= 0)
    {
    //routine runs here
    }

I'd like it to also run the same routine between the following time frame

    DateTime now = DateTime.Now; //get the current time
    //The DateTime constructor goes (YYYY, MM, DD, HH, MM, SS)
    DateTime start1 = new DateTime(now.Year, now.Month, now.Day, 23, 59, 00);
    DateTime end1 = new DateTime(now.Year, now.Month, now.Day, 22, 00, 00);

    while (now.CompareTo(start1) >= 0 && now.CompareTo(end1) <= 0)
    {
    //routine runs here
    }

How would I merge the (now.CompareTo(start) and (start1) as well as (end) and (end1)

Try this:

     DateTime now = DateTime.Now; //get the current time
    //The DateTime constructor goes (YYYY, MM, DD, HH, MM, SS)
    DateTime start = new DateTime(now.Year, now.Month, now.Day, 00, 00, 00);
    DateTime end = new DateTime(now.Year, now.Month, now.Day, 17, 25, 00);
    DateTime start1 = new DateTime(now.Year, now.Month, now.Day, 23, 59, 00);
    DateTime end1 = new DateTime(now.Year, now.Month, now.Day, 22, 00, 00);
    while (now.CompareTo(start) >= 0 && now.CompareTo(end)<= 0) || (now.CompareTo(start1) >= 0 && now.CompareTo(end1)<= 0)
    {
    //routine runs here
    }

Edited 3 Years Ago by tinstaafl

Thanks

Had to add another set of brackets to make it run, but it appears to work

while ((now.CompareTo(start) >= 0 && now.CompareTo(end)<= 0) || (now.CompareTo(start1) >= 0 && now.CompareTo(end1)<= 0))

New question/problem has arisen from this.

When the script runs, it holds DateTime start,start1,end,end1 in the varibles.

Once the now.Day advances 1 day, the CompareTo is no longer valid for that new day.

How do you re-work this to only compare Hours,Minutes,Seconds so the script would run every day without having to restart the script every day?

You shouldn't be holding those DateTime values outside the method that checks if it is the right time. Redo your logic.

More information about what you are trying to do might help us come up with a better method. Do you want the routine to run over and over again during those time frames or just one time?

Edited 3 Years Ago by Momerath

Because I was bored, I created how I'd do this. Please note that I believe in versatile code because I like to reuse things, or have the ability to do so.

First I'd create a Time class to hold the Time and just the Time:

using System;

namespace DreamInCode {
    struct Time : IComparable, IComparable<Time>, IEquatable<Time> {
        int hour;
        int minute;
        int second;

        public int Hour { get { return hour; } }
        public int Minute { get { return minute; } }
        public int Second { get { return second; } }

        public Time(int hour, int minute, int second) {
            while (second >= 60) {
                minute++;
                second -= 60;
            }

            while (minute >= 60) {
                hour++;
                minute -= 60;
            }

            this.second = second;
            this.minute = minute;
            this.hour = hour;
        }

        public Time(Time t) {
            this.hour = t.Hour;
            this.minute = t.Minute;
            this.second = t.Second;
        }

        public Time(DateTime dt) {
            this.hour = dt.Hour;
            this.minute = dt.Minute;
            this.second = dt.Second;
        }

        public static Time Now {
            get {
                return new Time(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);
            }
        }

        public int CompareTo(Time other) {
            if (this.Hour == other.Hour) {
                if (this.Minute == other.Minute) {
                    if (this.Second == other.Second) {
                        return 0;
                    } else {
                        return this.Second.CompareTo(other.Second);
                    }
                } else {
                    return this.Minute.CompareTo(other.Minute);
                }
            } else {
                return this.Hour.CompareTo(other.Hour);
            }
        }

        public int CompareTo(object obj) {
            if (obj is Time) {
                Time other = (Time)obj;
                return this.CompareTo(other);
            }

            throw new ArgumentException(String.Format("Can't compare object of type {0} to {1)", obj.GetType().ToString(), this.GetType().ToString()));
        }

        public bool Equals(Time other) {
            if (this.Hour == other.Hour && this.Minute == other.Minute && this.Second == other.Second) {
                return true;
            }

            return false;
        }

        public override Boolean Equals(Object obj) {
            if (obj is Time) {
                return this.Equals((Time)obj);
            }

            throw new ArgumentException(String.Format("Can't compare object of type {0} to {1)", obj.GetType().ToString(), this.GetType().ToString()));
        }

        public override int GetHashCode() {
            return this.GetHashCode();
        }

        public static Boolean operator >(Time a, Time b) {
            return a.CompareTo(b) > 0;
        }

        public static Boolean operator <(Time a, Time b) {
            return a.CompareTo(b) < 0;
        }

        public static Boolean operator >=(Time a, Time b) {
            return a.CompareTo(b) >= 0;
        }

        public static Boolean operator <=(Time a, Time b) {
            return a.CompareTo(b) <= 0;
        }

        public static Boolean operator ==(Time a, Time b) {
            return a.CompareTo(b) == 0;
        }

        public static Boolean operator !=(Time a, Time b) {
            return a.CompareTo(b) != 0;
        }
    }
}

I use a struct vs a class as I consider this type of thing as a value type. All the interface and operator overloading is to make life easier in other code.

Now for a range of times, so we have a start and an end:

using System;

namespace DreamInCode {
    struct TimeRange {
        Time start;
        Time end;

        public Time StartTime { get { return start; } }
        public Time EndTime { get { return end; } }

        public TimeRange(Time start, Time end) {
            this.start = start;
            this.end = end;
        }

        public Boolean InRange(Time t) {
            if (t >= StartTime && t <= EndTime) {
                return true;
            }

            return false;
        }
    }
}

Then, of course, something to hold multiple ranges and do some testing on them.

using System;
using System.Collections.Generic;

namespace DreamInCode {
    class TimeRangeCollection {
        private List<TimeRange> times = new List<TimeRange>();

        public TimeRangeCollection() {
        }

        public void Add(TimeRange range) {
            times.Add(range);
        }

        public Boolean Test(Time theTime) {
            Boolean result = false;

            foreach (TimeRange tr in times) {
                if (tr.InRange(theTime)) {
                    result = true;
                    break;
                }
            }

            return result;
        }
    }
}

If you've made it this far, good job! Now our code for using this would look something like this:

using System;

namespace DreamInCode {
    public class Demo {
        public static void Main() {
            TimeRangeCollection trc = new TimeRangeCollection();

            trc.Add(new TimeRange(new Time(0, 0, 0), new Time(1, 0, 0)));
            trc.Add(new TimeRange(new Time(4, 3, 10), new Time(11, 0, 0)));

            while (true) {
                if (trc.Test(new Time(DateTime.Now))) {
                    RunRoutine();
                }
            }
        }
    }
}

With this we can add new time ranges easily without having to modify the code, just include the new range. I didn't impliment a Remove on the TimeRangeCollection class, but you could do so allowing full dynamic control of the ranges. Another Add method that takes two times would also be something useful to implement.

In actual production code I'd include at least a SpinOnce() in the while loop to keep it from taking 100% of the CPU all the time.

Edited 3 Years Ago by Momerath

This article has been dead for over six months. Start a new discussion instead.