CronField.cs 2.81 KB
namespace NCC.TaskScheduler
{
    /// <summary>
    /// Cron 表达式内置字段
    /// </summary>
    internal sealed class CronField
    {
        private static readonly string[] MonthNames =
        {
            null, "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
        };

        private static readonly string[] DayOfWeekNames =
        {
            "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"
        };

        private static readonly int[] MonthNamesArray = new int[MonthNames.Length];
        private static readonly int[] DayOfWeekNamesArray = new int[DayOfWeekNames.Length];

        // 0 and 7 are both Sunday, for compatibility reasons.
        public static readonly CronField DaysOfWeek = new("Days of week", 0, 7, DayOfWeekNamesArray, false);

        public static readonly CronField Months = new("Months", 1, 12, MonthNamesArray, false);
        public static readonly CronField DaysOfMonth = new("Days of month", 1, 31, null, false);
        public static readonly CronField Hours = new("Hours", 0, 23, null, true);
        public static readonly CronField Minutes = new("Minutes", 0, 59, null, true);
        public static readonly CronField Seconds = new("Seconds", 0, 59, null, true);

        static CronField()
        {
            for (var i = 1; i < MonthNames.Length; i++)
            {
                var name = MonthNames[i].ToUpperInvariant();
                var array = new char[3];
                array[0] = name[0];
                array[1] = name[1];
                array[2] = name[2];

                var combined = name[0] | (name[1] << 8) | (name[2] << 16);

                MonthNamesArray[i] = combined;
            }

            for (var i = 0; i < DayOfWeekNames.Length; i++)
            {
                var name = DayOfWeekNames[i].ToUpperInvariant();
                var array = new char[3];
                array[0] = name[0];
                array[1] = name[1];
                array[2] = name[2];

                var combined = name[0] | (name[1] << 8) | (name[2] << 16);

                DayOfWeekNamesArray[i] = combined;
            }
        }

        public readonly string Name;
        public readonly int First;
        public readonly int Last;
        public readonly int[] Names;
        public readonly bool CanDefineInterval;
        public readonly long AllBits;

        private CronField(string name, int first, int last, int[] names, bool canDefineInterval)
        {
            Name = name;
            First = first;
            Last = last;
            Names = names;
            CanDefineInterval = canDefineInterval;
            for (var i = First; i <= Last; i++)
            {
                AllBits |= (1L << i);
            }
        }

        public override string ToString()
        {
            return Name;
        }
    }
}