1

I'm working on a task system where you can create repeating tasks, and there is one case that I need help to figure out:

enter image description here

I'm using this library to figure out when to create the tasks and to project the time it will spend in the next 28 days. For example, every day at 9:

CronExpression expression = CronExpression.Parse("0 9 * * *");

But reading about the Cronos expression I still couldn't figure out how to get an expression That would repeat every 3 weeks. Which days of the week OK, but every x weeks I can't figure out.

Can you help me please? Thanks

André Luiz
  • 6,642
  • 9
  • 55
  • 105

2 Answers2

0

I dont think you can schedule a cron based on weeks, see below: I would suggest scheduling the same job for different days of the month.

┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of the month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
│ │ │ │ │                                   7 is also Sunday on some systems)
│ │ │ │ │
│ │ │ │ │
* * * * * command to execute

https://en.wikipedia.org/wiki/Cron

Pieter Alberts
  • 829
  • 1
  • 7
  • 23
0

There is no way to do this with cron expressions. In my case, I needed the occurrences to make some cost calculation. This is the function I made that seems to be working fine:

        public List<DateTime> GetOccurrencesInWeeksInterval(DateTime start, DateTime end)
    {
        var ret = new List<DateTime>();
        DateTime? lastDate = null;
        int weekInterval = _rptConfig.Interval;

        CronExpression expression = CronExpression.Parse(this.GetCronExpression()); // this would return something like "0 9 * * 1,3,5"
        var dates = expression.GetOccurrences(start, end).ToList();

        if (weekInterval == 1) {
            return dates;
        }

        if (dates.Any())
        {
            foreach (var date in dates)
            {
                if (lastDate == null)
                {
                    ret.Add(date);
                    lastDate = date;
                }
                else
                {
                    var weekDiff = HelperFunctions.GetWeekDiff(lastDate.Value, date);
                    if (weekDiff == 0)
                    {
                        ret.Add(date);
                    }
                    else if (weekDiff > 0 && (weekDiff % weekInterval) == 0)
                    {
                        ret.Add(date);
                    }
                }
            }
        }

        return ret;
    }

This is the GetWeekDiff function:

        /// <summary>
    /// https://stackoverflow.com/questions/49924085/week-difference-between-2-dates-in-c-sharp#49924454
    /// </summary>
    /// <param name="dtStart"></param>
    /// <param name="dtEnd"></param>
    /// <returns></returns>
    public static int GetWeekDiff(DateTime dtStart, DateTime dtEnd, DayOfWeek startOfWeek = DayOfWeek.Monday) {

        //===============================================
        var diff = dtEnd.Subtract(dtStart);
        var weeks = (int)diff.Days / 7;

        // need to check if there's an extra week to count
        var remainingDays = diff.Days % 7;
        var cal = CultureInfo.InvariantCulture.Calendar;
        var d1WeekNo = cal.GetWeekOfYear(dtStart, CalendarWeekRule.FirstFullWeek, startOfWeek);
        var d1PlusRemainingWeekNo = cal.GetWeekOfYear(dtStart.AddDays(remainingDays), CalendarWeekRule.FirstFullWeek, startOfWeek);

        if (d1WeekNo != d1PlusRemainingWeekNo)
            weeks++;

        return weeks;

    }

Hope this helps someone because I realized this is a pretty common question.

André Luiz
  • 6,642
  • 9
  • 55
  • 105