Universal.Common.Cron
1.0.0
dotnet add package Universal.Common.Cron --version 1.0.0
NuGet\Install-Package Universal.Common.Cron -Version 1.0.0
<PackageReference Include="Universal.Common.Cron" Version="1.0.0" />
<PackageVersion Include="Universal.Common.Cron" Version="1.0.0" />
<PackageReference Include="Universal.Common.Cron" />
paket add Universal.Common.Cron --version 1.0.0
#r "nuget: Universal.Common.Cron, 1.0.0"
#:package Universal.Common.Cron@1.0.0
#addin nuget:?package=Universal.Common.Cron&version=1.0.0
#tool nuget:?package=Universal.Common.Cron&version=1.0.0
Universal.Common.Cron
A dependency-free cron expression parser and next-occurrence calculator for .NET. Standard 5-field POSIX/vixie-cron syntax (crontab(5)), including the "day-of-month OR day-of-week" rule most alternatives get wrong.
using Universal.Common.Cron;
CronExpression cron = CronExpression.Parse("0 9 * * 1-5"); // weekdays at 9am -- throws FormatException if invalid
if (!CronExpression.TryParse(userInput, out CronExpression? parsed, out string? error))
Console.WriteLine(error); // e.g. "minute field '60': must be within 0-59."
DateTimeOffset? next = cron.NextAfter(DateTimeOffset.UtcNow); // next matching instant
bool firesNow = cron.Matches(DateTimeOffset.UtcNow); // does it fire right now?
var nextFive = cron.GetOccurrences(DateTimeOffset.UtcNow) // lazy sequence -- always bound it
.Take(5);
NextAfter/Matches/GetOccurrences take an optional TimeZoneInfo (default TimeZoneInfo.Local), with correct DST handling (spring-forward gap never fires; fall-back overlap fires once).
Equality compares expanded field sets plus day-of-month/day-of-week wildness (the two flags that affect matching — see below), not spelling — "*/30 * * * *" and "0,30 * * * *" are Equal, but "0 0 * * 5" and "0 0 1-31 * 5" are not, despite an identical day-of-month set, because one is wild and the other isn't. ToString() returns the original source text.
Wildness: * vs. an explicit full range
IsMinuteWild/IsHourWild/IsDayOfMonthWild/IsMonthWild/IsDayOfWeekWild report whether a field is a literal */*/N, not whether its expanded set happens to cover every value. This matters because real cron's day-of-month-OR-day-of-week rule keys off the literal token: "0 0 15 * 0-6" fires every day (an explicit 0-6, unlike *, keeps day-of-week "restricted," so the OR rule kicks in and its trivially-always-true condition wins), while "0 0 15 * *" fires only on the 15th.
Supported syntax
*, */N, N-M, N-M/N, comma lists, day/month names (MON-FRI, JAN), Sunday as 0 or 7.
Not supported: seconds field, L/W/#/?, 1-based day-of-week, year field (a different, incompatible Quartz-family dialect) — and, within this dialect, wraparound ranges (11-2 for Nov–Feb) are rejected, matching real cron.
License
CC0-1.0 (public domain).
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Universal.Common.Cron:
| Package | Downloads |
|---|---|
|
Universal.Operative.Sdk.Scheduling
Durably schedule a prompt to fire into a Universal.Operative.Sdk IOperative at a future time, either once or on a recurring cron schedule — it fires even if this process wasn't running when the schedule came due. ScheduleCreate/List/Cancel tools (backed by a shared ScheduleService, reusable from an HTTP-facing admin surface too) durably register atomically on creation, roll back on failure. IDurableScheduleBackend implementations: WindowsTaskSchedulerBackend/SystemdTimerBackend/CrontabBackend register with the OS's own scheduler; HttpDurableScheduleBackend registers against a remote HTTP dispatcher instead, for hosts (e.g. a sandboxed PaaS container) with no local OS scheduler reachable at all. Every backend is fully configured at construction — RegisterAsync just needs the schedule. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 190 | 7/27/2026 |
1.0.0 -- Initial release.