atifaziz / NCrontab

Crontab for .NET

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Persian Calendar to parse CRON expressions

alirezapooneh opened this issue · comments

Hi all,
I want to run recurring task in Hangfire by CRON expression like (* 10 1 * * ) to run at 10 of first day of month, But I want to run first day of persian calendar month(Farvardin,Ordibehesht,…).
Hangfire use NCrontab to parse CRON expressions.
Is it possible to change locale or calendar or implement any to support it?

Is it possible to change locale or calendar…?

No in the current version.

…or implement any to support it?

It could certainly be implemented but it would be best if it's spec'd out by someone who understands the intricate details of the Persian calendar. I certainly don't have the knowledge. Even if this project adds support, it doesn't guarantee that Hangfire will.

Thanks a lot.
Can you help me how I can implement Persian calendar in NCornTab?
Persian Calendar is supported in .NET Framework 4.5 and higher, and I can add it to any library if I know about how I must implement it.

Can you help me how I can implement Persian calendar in NCornTab?

Two problems:

  1. I don't completely understand what the expected outcome should be.
  2. If I understand the problem and it's simple enough, it might take me as much time to explain as to implement it. 😉

You can help with 1 by explaining what the expectation is (e.g. do you expect to use English names for Persian months and week days?) and adding unit tests that would fail, showing lack of support, and which then one could go about fixing.

In case you want to do a spike, the NCrontab calendar is fixed here in CrontabSchedule:

static Calendar Calendar => CultureInfo.InvariantCulture.Calendar;

It is then used in two places to get the maximum supported year:

//
// Stop processing when year is too large for the datetime or calendar
// object. Otherwise we would get an exception.
//
if (year > Calendar.MaxSupportedDateTime.Year)
return null;

and the days in a month:

if (day > 28 && dateChanged && day > Calendar.GetDaysInMonth(year, month))
{
if (year >= endYear && month >= endMonth && day >= endDay)
return endTime;
day = nil;
goto RetryDayMonth;
}

Without any design work, the first thing would be to see if replacing the invariant culture calendar with the Persian one passes the unit tests based on the Persian calendar.

Then, the month and week day names are hard-wired in English in CrontabFieldImpl:

public static readonly CrontabFieldImpl Month = new CrontabFieldImpl(CrontabFieldKind.Month, 1, 12, new[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" });
public static readonly CrontabFieldImpl DayOfWeek = new CrontabFieldImpl(CrontabFieldKind.DayOfWeek, 0, 6, new[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" });

My guess is therefore that these area will need to be somehow made configurable to support an alternative calendar. The Persian calendar seems (from what I read up quickly) quite straightforward in that it has 12 months and 365 days so I don't anticipate too many issues (though I might be underestimating the effort given my lack of knowledge).

I review source code yesterday and find static calendar instance that all calculation are done by it.
All description about Persian Calendar found in https://docs.microsoft.com/en-us/dotnet/api/system.globalization.persiancalendar?view=netframework-4.7.2

I think Calendar instance must be a culture specific calendar like it:
static Calendar Calendar => new CultureInfo("fa-IR").Calendar