Выберите день из периода - повторение

Я пытаюсь реализовать шаблон повторения для своего календарного приложения. Я хочу, чтобы он работал так же, как Outlook, когда вы назначаете встречу с повторением.

public async Task<ValidationResponse<ReccurrenceModel>> ApplyReccurrencePeriod (string userName, ReccurrenceModel value)
        {
            var user = await repository.FindByUserName(userName);

            var fromDateUTC = DateTime.SpecifyKind(value.FromDate, DateTimeKind.Utc);
            var toDateUTC = DateTime.SpecifyKind(value.ToDate, DateTimeKind.Utc);

            var dates = new List<DateTime>();
            var weeklyReccurrence = value.weeklyReccurrence;

            if (value.IsMonday == true)
            {
                var fromDate = value.FromDate;
                var toDate = value.ToDate;
                for (var dt = fromDate; dt < toDate; dt = dt.AddDays(1))
                {
                    dates.Add(dt);
                }
                var savedDates = dates.Where(x => x.DayOfWeek == DayOfWeek.Monday).Select(x => x.Date);
            }
// I do the same code to verify every week day 

                var test = dates.Where(x => x.DayOfWeek == DayOfWeek.Friday).Select(x => x.Date);
            }

            foreach (var date in savedDates) {
                var x = user.Holidays.FirstOrDefault(kvp => kvp.Key == date
                                     && kvp.Value.StateVal == value.State.StateVal);

                var dateUTC = DateTime.SpecifyKind(date, DateTimeKind.Utc);

                user.Holidays[dateUTC] = value.State;

            }
            // save
            var updatedUser = await repository.UpdateEmployee(user);
            return await Task.FromResult(new ValidationResponse<HolidayModel>()
            {
                IsValid = true,
                Result = updatedUser.Holidays.ContainsKey(dateUTC) ? new HolidayModel() { Date = dateUTC, State = updatedUser.Holidays[dateUTC] } : null
            });

        }
    }

Проблема с моим кодом в том, что он работает, только если я повторяюсь еженедельно. Мне нужно заставить его работать, чтобы повторение длилось 2, 3, ... n недель. Как я могу пропустить несколько недель?

 public class ReccurrenceModel
    {
        public DateTime FromDate { get; set; }
        public DateTime ToDate { get; set; }
        public int WeeklyReccurrence { get; set; }
        public State State { get; set; }
        public bool IsMonday { get; set; }
        public bool IsTuesday { get; set; }
        public bool IsWednesday { get; set; }
        public bool IsThursday { get; set; }
        public bool  IsFriday { get; set; }
        public DateTime FromDateToReturn { get; set; }
        public DateTime ToDateToReturn { get; set; }
    }

Чего именно вы здесь пытаетесь достичь? Как именно здесь должен работать шаблон повторения?

Fabjan 31.10.2018 13:20

Пожалуйста, опишите проблемы, которые у вас возникли. Что произойдет, если вы установите его на 2, 3 .. n недели

DaImTo 31.10.2018 13:24

Мне нужен список каждый понедельник и пятницу с 01.05.2018 по 01.12.2018, но не еженедельно, например, каждые 3 недели.

user2004 31.10.2018 13:24

Мой код возвращает эти дни каждую неделю, и я хочу пропустить несколько недель, используя переменную weeklyReccurrence.

user2004 31.10.2018 13:28

Что это за тип weeklyReccurrence? Пожалуйста, добавьте также код для ReccurrenceModel

Fabjan 31.10.2018 13:37

@Fabjan, я сделал прямо сейчас, извините за это. Это int: D

user2004 31.10.2018 13:42

Попробуйте использовать мой реализация повторений RFC 2445. Указанное выше правило будет выражено в виде двух повторений: FREQ=WEEKLY;BYDAY=MO;INTERVAL=3;UNTIL=2018-12-01 и одного для пятницы. Насколько я понимаю, RFC 2445 (и RFC 5545) не позволяет выразить это (два рабочих дня каждые три недели) как одно правило повторения, но оно имеет то преимущество, что является стандартом.

Anton Tykhyy 31.10.2018 14:11

Я считаю, что этот вопрос относится к CodeReview, а не к StackOverflow, пожалуйста, отправляйтесь туда и опубликуйте свой вопрос там, чтобы получить лучший ответ, в этом коде есть некоторые проблемы, которые можно решить с помощью обзора.

Oscar Guillamon 31.10.2018 14:15
2
8
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Код немного запутан, есть много строк, которые вообще ничего не делают.

Здесь я предоставляю образец кода, который, хотя и не совсем элегантный, но обеспечивает необходимое поведение. Следующий код создаст список дней, которые повторяются каждые 2, 3, независимо от того, какие недели вы укажете в его вызове.

Этот метод также принимает список DayOfWeek, для которого вы хотите создать повторение.

private static void GetRecurrentDays(DateTime fromDate, DateTime untilDate, uint weeklyRecurrence, List<DayOfWeek> recurrenceDays)
{
    var recurrenceDates = new List<DateTime>();
    for (var dt = fromDate; dt < untilDate; dt = dt.AddDays(1))
    {
        if (recurrenceDays.Any(day => day.Equals(dt.DayOfWeek)))
        {
            var lastDate = 
                recurrenceDates
                    .LastOrDefault(date => date.DayOfWeek.Equals(dt.DayOfWeek));

            // We multiply 7 days (a week) with weeklyRecurrence to 
            // calculate the appropiate date in which to add another day, 
            // calling with either 0 or 1 will calculate a weekly 
            // schedule
            if (lastDate.Equals(DateTime.MinValue) 
                || weeklyRecurrence.Equals(0)
                || ((dt - lastDate).Days % (7 * weeklyRecurrence)).Equals(0) )
            {
                recurrenceDates.Add(dt);
            }
        }
    }
}

вы можете встроить этот код в свой, чтобы получить дни с еженедельным повторением, а затем использовать их в своем коде.

Другие вопросы по теме