Zaiets.Cron.Parser 1.0.0

dotnet add package Zaiets.Cron.Parser --version 1.0.0
                    
NuGet\Install-Package Zaiets.Cron.Parser -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Zaiets.Cron.Parser" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Zaiets.Cron.Parser" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Zaiets.Cron.Parser" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Zaiets.Cron.Parser --version 1.0.0
                    
#r "nuget: Zaiets.Cron.Parser, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Zaiets.Cron.Parser@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Zaiets.Cron.Parser&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Zaiets.Cron.Parser&version=1.0.0
                    
Install as a Cake Tool

Zaiets.Cron.Parser

A production-ready cron expression parser and scheduler for .NET 10.
Parse any standard cron string, calculate the next (or previous) run time, enumerate future occurrences, and get plain-English descriptions — all with zero dependencies.

NuGet License: MIT


Installation

dotnet add package Zaiets.Cron.Parser

Quick start

using Zaiets.Cron.Parser;

var cron = CronExpression.Parse("*/15 9-17 * * 1-5");

// Next occurrence from now
DateTime? next = cron.GetNextOccurrence(DateTime.UtcNow);

// Human-readable description
Console.WriteLine(cron.Describe());
// → "Every 15 minutes past every hour, on weekdays (Monday through Friday)"

// Next 5 occurrences
foreach (var t in cron.GetNextOccurrences(DateTime.UtcNow, 5))
    Console.WriteLine(t.ToString("u"));

Expression format

5-field (minute resolution) — standard Unix cron

┌─────── minute       0–59
│ ┌───── hour         0–23
│ │ ┌─── day-of-month 1–31
│ │ │ ┌─ month        1–12  (or JAN–DEC)
│ │ │ │ ┌ day-of-week 0–6   (0 = Sunday; 7 also accepted; or SUN–SAT)
* * * * *

6-field (second resolution)

┌───────── second 0–59
│ ┌─────── minute
│ │ ┌───── hour
│ │ │ ┌─── day-of-month
│ │ │ │ ┌─ month
│ │ │ │ │ ┌ day-of-week
* * * * * *

Value syntax

Syntax Meaning Example
* Every value * * * * *
? Don't care (DOM / DOW only) 0 0 ? * 1
n Exact value 30 9 * * *
n-m Range (inclusive) 1-5
*/step Every step values from min */15
n/step Every step values starting at n 5/10
n-m/step Every step values within a range 0-30/5
a,b,c List of values/ranges 1,15,29

@ presets

Preset Equivalent
@yearly 0 0 1 1 *
@annually 0 0 1 1 *
@monthly 0 0 1 * *
@weekly 0 0 * * 0
@daily 0 0 * * *
@midnight 0 0 * * *
@hourly 0 * * * *
@minutely * * * * *

API reference

CronExpression

// Parsing
CronExpression expr = CronExpression.Parse("0 */2 * * *");
bool ok = CronExpression.TryParse("bad expr", out CronExpression? expr);

// Schedule properties
bool hasSeconds = expr.HasSeconds;
string raw      = expr.Expression;

// Occurrence calculation
DateTime? next  = expr.GetNextOccurrence(DateTime.UtcNow);
DateTime? next2 = expr.GetNextOccurrence(from, endAt);   // bounded
DateTime? prev  = expr.GetPreviousOccurrence(DateTime.UtcNow);

IEnumerable<DateTime> range = expr.GetOccurrences(from, endAt);
IEnumerable<DateTime> next5 = expr.GetNextOccurrences(DateTime.UtcNow, 5);

// Matching
bool matches = expr.IsMatch(someDateTime);

// Description
string desc = expr.Describe();   // "Every 2 hours"
string str  = expr.ToString();   // "0 */2 * * *  —  Every 2 hours"

CronPresets — named constants and factory helpers

// String constants (safe to store in config)
CronPresets.Every5Minutes    // "*/5 * * * *"
CronPresets.Hourly           // "@hourly"
CronPresets.Daily            // "@daily"
CronPresets.BusinessHours    // "0 9-17 * * 1-5"

// Fluent factories
CronExpression e1 = CronPresets.Every(15);                         // every 15 min
CronExpression e2 = CronPresets.DailyAt(hour: 9, minute: 30);     // 09:30 every day
CronExpression e3 = CronPresets.WeeklyOn(DayOfWeek.Monday);       // Mon at midnight
CronExpression e4 = CronPresets.MonthlyOn(dayOfMonth: 1);         // 1st of each month
CronExpression e5 = CronPresets.Weekdays(hour: 8);                 // Mon–Fri at 08:00
CronExpression e6 = CronPresets.Weekends(hour: 10);                // Sat+Sun at 10:00
CronExpression e7 = CronPresets.EveryHours(6);                     // every 6 hours

CronExtensions — extension methods

using Zaiets.Cron.Parser;

// On DateTime
DateTime?             next  = DateTime.UtcNow.GetNextCronOccurrence("@daily");
IEnumerable<DateTime> range = DateTime.UtcNow.GetCronOccurrences("*/5 * * * *", endAt);
bool                  match = someDate.MatchesCron("0 9 * * 1-5");
TimeSpan?             wait  = DateTime.UtcNow.TimeUntilNextCron("0 0 * * *");

// On string
CronExpression expr  = "*/30 * * * *".ToCronExpression();
CronExpression? safe = "bad".ToCronExpressionOrNull();
string          desc = "0 9 * * MON-FRI".DescribeCron();
bool            ok   = "*/5 * * * *".IsValidCron();

Examples

Background job scheduling

public class CronBackgroundService : BackgroundService
{
    private readonly CronExpression _schedule = CronExpression.Parse("0 */6 * * *");

    protected override async Task ExecuteAsync(CancellationToken ct)
    {
        while (!ct.IsCancellationRequested)
        {
            var next = _schedule.GetNextOccurrence(DateTime.UtcNow);
            if (next is null) break;

            var delay = next.Value - DateTime.UtcNow;
            if (delay > TimeSpan.Zero)
                await Task.Delay(delay, ct);

            await DoWorkAsync(ct);
        }
    }
}

Validate and describe user-supplied schedules

string input = Request.Form["schedule"];

if (!input.IsValidCron())
    return BadRequest("Invalid cron expression.");

var cron = input.ToCronExpression();
string description = cron.Describe();
DateTime? nextRun  = cron.GetNextOccurrence(DateTime.UtcNow);

return Ok(new { description, nextRun });

List upcoming occurrences

var cron  = CronExpression.Parse("0 9 * * 1-5");   // 9 AM weekdays
var from  = DateTime.UtcNow;
var until = from.AddDays(14);

var schedule = cron.GetOccurrences(from, until)
                   .Select(d => d.ToString("ddd dd MMM HH:mm"))
                   .ToList();

Day-of-week with OR semantics

When both DOM and DOW are restricted (non-wildcard), occurrences fire if either condition is satisfied — matching standard Unix/Quartz behaviour.

// Fires on the 15th of every month OR every Monday
var cron = CronExpression.Parse("0 0 15 * 1");

License

MIT — see LICENSE.


Author: Vladyslav Zaiets · sarmkadan.com

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 120 5/3/2026