Как хранить, сравнивать и возвращать даты расписания, заданные в виде cron-строки - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть класс для установки и расчета времени по расписанию.Расписание задается cron-подобными строками с блэкджеком и разделителями в виде точек (для даты) и двоеточий (для времени).Пример: 2009,2010,2015-2030/3.*.08-25 */4:0-59/3:*.100.Каждая часть даты / времени может быть установлена ​​в виде списков и диапазонов.Фракция устанавливает шаг в списке.Я анализирую строку в конструкторе класса и получаю 7 массивов int (годы ... миллисекунды) и инициализирую 7 полей класса, потому что я не хочу, чтобы экземпляр класса сохранял огромный список / массив DateTimes со всеми возможными датами .:

 public class Schedule
    {
        List<int> years = new List<int>();
        List<int> months = new List<int>();
        List<int> days = new List<int>();
        List<int> hours = new List<int>();
        List<int> minutes = new List<int>();
        List<int> seconds = new List<int>();
        List<int> milliseconds = new List<int>();
        List<int> daysOfWeek = new List<int>();

Теперь я начал реализовывать методы класса:

//Returns the next moment closest to the specified time in 
//the schedule or the specified time itself, if it is in the schedule.
public DateTime NearestEvent(DateTime t1)

//Returns the next time in the schedule. t1 -Time to step back from.
public DateTime NextEvent(DateTime t1)

//Returns the previous time in the schedule
public DateTime PrevEvent(DateTime t1)

Метод NearestEvent делает что-то подобное для всех частей dateTime и почти всегда работает правильно:

public DateTime NearestEvent(DateTime t1)
            {
                int resYear = 0; int resMonth = 0; int resDay = 0; int resHour = 0; int resMinute = 0; int resSecond = 0; int resMillisecond = 0;
                int t1Year = t1.Year;
                int t1Month = t1.Month;
                int t1Day = t1.Day;
                int t1Hour = t1.Hour;
                int t1Minute = t1.Minute;
                int t1Second = t1.Second;
                int t1Millisecond = t1.Millisecond;


                int minDifference = Math.Abs(this.years[0] - t1Year);
                int index = 0;
                 bool isAlreadySet = false;


            for (int i = 1; i < this.years.Count; i++)
            {
                if (this.years[i] == t1Year)
                {
                    resYear = this.years[i];
                    isAlreadySet = true;
                    break;
                }
                if (Math.Abs(this.years[i] - t1Year) < minDifference && (this.years[i] - t1Year) >= 0)
                {
                    minDifference = this.years[i] - t1Year;
                    index = i;
                }

            }
            if (!isAlreadySet)
            {
                resYear = this.years[index];
            }
..........
return new DateTime(resYear, resMonth, resDay, resHour, resMinute, resSecond, resMillisecond);

Но для NextEvent и PrevEvent этот способ не подходит и не может предложить другое очевидное решение.Может я неправильно храню данные полученные из строки расписания?Кто-нибудь может сказать мне идею решения или кода?

...