TimeGrid.NET
0.1.3
dotnet add package TimeGrid.NET --version 0.1.3
NuGet\Install-Package TimeGrid.NET -Version 0.1.3
<PackageReference Include="TimeGrid.NET" Version="0.1.3" />
<PackageVersion Include="TimeGrid.NET" Version="0.1.3" />
<PackageReference Include="TimeGrid.NET" />
paket add TimeGrid.NET --version 0.1.3
#r "nuget: TimeGrid.NET, 0.1.3"
#:package TimeGrid.NET@0.1.3
#addin nuget:?package=TimeGrid.NET&version=0.1.3
#tool nuget:?package=TimeGrid.NET&version=0.1.3
TimeGrid.NET
Business-hours, availability, downtime, capacity, and SLA working-time calculations for .NET.
TimeGrid.NET turns schedule rules into a queryable operational timeline. Define working hours, lunch breaks, holidays, maintenance windows, capacity overrides, and named schedule entries; serialize the source definition as JSON; compile it once; then answer timestamp and range queries quickly.
Use it for factory calendars, machine availability, SLA clocks, business-hour math, capacity-aware slot search, and systems that need a dependable time layer before they schedule, simulate, dispatch, or report.
Not a scheduler. Not a simulator. Not a timezone database. TimeGrid.NET is the availability and working-time engine those systems can depend on.
Install
dotnet add package TimeGrid.NET
30-Second Example
Calculate an SLA due date while skipping lunch, nights, weekends, and one-off closures:
using TimeGrid;
var calendar = TimeGridCalendar
.Weekdays(new TimeOnly(9, 0), new TimeOnly(17, 0))
.BreakWeekdays(new TimeOnly(12, 0), new TimeOnly(13, 0))
.Close(new DateOnly(2026, 1, 1))
.SetClosedWindow("company-offsite", new DateTime(2026, 1, 7, 13, 0, 0), new DateTime(2026, 1, 7, 17, 0, 0));
var openedAt = new DateTime(2026, 1, 5, 11, 0, 0);
var trace = calendar.At(openedAt).TraceWorkDuration(10.Hours());
Console.WriteLine(trace.Result);
foreach (var step in trace.Steps)
{
Console.WriteLine($"{step.Window}: {step.Duration}");
}
Practical Examples
Runnable examples live in examples/:
dotnet run --project examples/TimeGrid.Examples -- all
dotnet run --project examples/TimeGrid.Examples -- sla
dotnet run --project examples/TimeGrid.Examples -- manufacturing
dotnet run --project examples/TimeGrid.Examples -- fleet
dotnet run --project examples/TimeGrid.Examples -- json
dotnet run --project examples/TimeGrid.Examples -- overnight
| Example | What it shows |
|---|---|
sla |
Business-hour due dates and consumed working windows. |
manufacturing |
Downtime, capacity boosts, and first slot with enough capacity. |
fleet |
Several compiled machine timelines queried at the same timestamp. |
json |
JSON schedule templates plus per-machine exceptions. |
overnight |
Open rules that cross midnight and breaks inside overnight shifts. |
What It Answers
| Question | API |
|---|---|
| Can this machine, team, or queue work now? | timeline.Analyze(now).CanWork |
| What is the effective capacity at this timestamp? | analysis.Capacity |
| Which state window contains this timestamp? | analysis.CurrentWindow |
| When does the state change next? | analysis.NextTransition |
| Why is this timestamp blocked or boosted? | calendar.At(now).Analyze().Matches |
| How much usable business time exists in a range? | timeline.GetWorkingDuration(start, end) |
| Where is the first continuous slot with enough capacity? | timeline.FindFirstSlot(start, 2.Hours(), 3) |
Schedule Definitions
TimeGrid.NET stores source rules, not compiled runtime state. That makes definitions easy to save, review, ship, and apply to many operational entities:
using TimeGrid;
var templateJson = TimeGridCalendar
.Create()
.OpenWeekdays(new TimeOnly(7, 0), new TimeOnly(19, 0))
.BreakWeekdays(new TimeOnly(12, 0), new TimeOnly(12, 45))
.Capacity(3)
.ToJson(indented: true);
var template = TimeGridCalendar.FromJson(templateJson).ToDefinition();
var machine = template
.ToCalendar()
.SetClosedWindow("machine-42-maintenance", new DateTime(2026, 1, 5, 15, 0, 0), new DateTime(2026, 1, 5, 17, 0, 0))
.SetCapacityWindow("machine-42-overtime-crew", new DateTime(2026, 1, 5, 17, 0, 0), new DateTime(2026, 1, 5, 19, 0, 0), 5)
.Compile(new DateTime(2026, 1, 5), new DateTime(2026, 1, 6));
TimeGrid.NET uses System.Text.Json source generation for its definition model.
Compile For Repeated Reads
Use Compile(start, end) when the same calendar will be queried many times. A compiled
timeline is read-only and answers point and range queries by searching precomputed state
segments.
var timeline = calendar.Compile(monthStart, monthEnd);
var point = timeline.Analyze(now);
var work = timeline.GetWorkingDuration(dayStart, dayEnd);
var slot = timeline.FindFirstSlot(dayStart, 4.Hours(), minimumCapacity: 2);
Why It Is Fast
| Operation | Runtime strategy |
|---|---|
| Point analysis | Binary search over compiled state segments |
| Range analysis | Binary search, then scan touched segments only |
| Transition lookup | Segment boundary lookup |
| Working duration | Sum usable segment ticks |
| Slot search | Scan continuous capacity-matching segments |
| JSON | Source-generated System.Text.Json definition serialization |
Local quick-query measurement on .NET 8.0, Windows 10, Intel Core i7-10700, Release build:
| Scenario | Operation | Result |
|---|---|---|
| 50,000 compiled state segments | GetCapacityAt |
0.053 us/query |
| 50,000 compiled state segments | Analyze |
0.067 us/query |
| 1,000 compiled machine timelines | GetCapacityAt sweep |
25.752 us |
| 1,000 compiled machine timelines | Analyze sweep |
35.944 us |
Measurements exclude compile time and run against already compiled timelines.
Good Fit
| Use TimeGrid.NET for | Use something else for |
|---|---|
| Business-hours and working-time calculations | Calendar UI rendering |
| Manufacturing availability and machine downtime | Queue dispatching |
| Capacity-aware slot search | Optimization solving |
| SLA clocks and operational reporting | Full timezone database behavior |
| JSON-backed schedule definitions | General-purpose date-range value objects |
| Scheduler or simulator availability layer | Running background jobs |
Core Rules
- Time windows are half-open:
[start, end). - Capacity
0means unavailable. - Capacity overrides split the timeline into state segments.
- JSON stores source definitions, not compiled timelines.
- Compiled timelines are read-only and optimized for repeated analysis.
- Use
DateTimeconsistently in your chosen local or UTC convention.
Direct APIs
calendar.CanWork(now);
calendar.GetCapacityAt(now);
calendar.GetWindowsAt(now);
calendar.GetPreviousTransitionTime(now);
calendar.GetNextTransitionTime(now);
calendar.GetOpenWindows(start, end);
calendar.GetUnavailableWindows(start, end);
calendar.GetStateWindows(start, end);
calendar.GetWorkingDuration(start, end);
calendar.FindFirstSlot(start, 2.Hours(), minimumCapacity: 2);
Links
- NuGet: https://www.nuget.org/packages/TimeGrid.NET
- Repository: https://github.com/code-gihan/timegrid-csharp
- Issues: https://github.com/code-gihan/timegrid-csharp/issues
- Python package: https://pypi.org/project/timegrid/
- License: MIT
If TimeGrid.NET gives you a wrong answer, a confusing error, or a missing API for a real scheduling or availability problem, please open a GitHub issue with the smallest calendar definition and query that reproduces it.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 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. |
-
net10.0
- No dependencies.
-
net8.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.
Add practical runnable examples and improve README discoverability for business-hours, availability, downtime, capacity, and SLA working-time use cases.