Chneau.OpenHours
1.0.2
dotnet add package Chneau.OpenHours --version 1.0.2
NuGet\Install-Package Chneau.OpenHours -Version 1.0.2
<PackageReference Include="Chneau.OpenHours" Version="1.0.2" />
<PackageVersion Include="Chneau.OpenHours" Version="1.0.2" />
<PackageReference Include="Chneau.OpenHours" />
paket add Chneau.OpenHours --version 1.0.2
#r "nuget: Chneau.OpenHours, 1.0.2"
#:package Chneau.OpenHours@1.0.2
#addin nuget:?package=Chneau.OpenHours&version=1.0.2
#tool nuget:?package=Chneau.OpenHours&version=1.0.2
openhours-cs
A high-performance, zero-allocation C# (.NET 10) parser and interval-math evaluator for OpenStreetMap opening_hours specifications.
โก Features & Performance
- $O(1)$ Hardware-Accelerated Bitmask Table: Evaluates
IsOpenin ~2.0 nanoseconds (>500 Million ops/sec) via embedded[InlineArray(158)] Bitmask158scalar bit tests (BTQ). - Zero-Allocation Interval Math: Zero heap allocations on query paths (
IsOpen,GetTimeToOpen,GetTimeToOpenForDuration,When,NextDur,NextDate). - Span-Based Parsing: Zero string allocations when parsing UTF-8 bytes or raw
ReadOnlySpan<char>. - Lock-Free Interning: Automatic lock-free deduplication and caching of parsed expressions.
- Overnight Shifts: Full support for shifts spanning midnight (e.g.
Mo 22:00-04:00,Su 22:00-04:00). - Overrides & Exclusions: Handles
off/closedrules overriding previous rules (e.g.Mo-Su 00:00-24:00; Tu 12:00-13:00 off). - Duration Availability: Find wait times for contiguous tasks of duration $D$ (
GetTimeToOpenForDuration/When). - Reflection-free JSON Decode: High-speed, zero-allocation
DecodeJson(ReadOnlySpan<byte>)deserializing in ~31 nanoseconds. - Source-Generated JSON: Native
System.Text.Jsonconverter andOpenHoursJsonContextfor seamless serialization.
๐ง Optimizations & Engineering Architecture
The C# (.NET 10) implementation applies several state-of-the-art runtime and JIT-level optimizations:
Dual State Representation &
[InlineArray(158)]:- Disjoint Interval Array (
TimeWindow[]): Flat sorted array of{ int Start, int End }minute intervals. - Contiguous Bitmask Struct: Employs .NET C# 12
[InlineArray(158)] struct Bitmask158(158 รulong= 10,080 bits) embedded directly inside the object payload. This enables zero heap indirection and compiles to singleBTQ/ bit-test instructions forIsOpen(~2.0 ns).
- Disjoint Interval Array (
Reflection-Free JSON Fast Path:
DecodeJson(ReadOnlySpan<byte>)performs direct UTF-8 byte scanning, escape validation, and resolves directly to interned instances via zero-allocation span lookups in ~31 ns.
Zero-Allocation Stack & Span Parsing:
- Parses expressions directly using
ReadOnlySpan<char>withstackalloc OpeningRule[8]andstackalloc TimeWindow[32]buffers. - Character classification uses fast ASCII bitwise arithmetic (
(c0 << 8) | c1pair matching for day tokens), completely avoiding string allocations during parsing.
- Parses expressions directly using
Two-Tier Lock-Free Caching Hierarchy:
- L1
[ThreadStatic]Fast Cache: Caches the last resolved string key andOpenHoursinstance per thread, skipping dictionary lookups for tight loops and consecutive parses. - L2 Concurrent Dictionary: Uses
ConcurrentDictionary<string, OpenHours>withGetAlternateLookup<ReadOnlySpan<char>>()to query span inputs without allocating string keys.
- L1
$O(\log N)$ Interval Binary Search:
- Fast binary search over the
windowsarray for duration calculations (GetTimeToOpen,When,NextDur), unrolled for small window counts.
- Fast binary search over the
[MethodImpl(MethodImplOptions.AggressiveInlining)]:- Applied across all hot evaluation paths to eliminate function call overhead and enable downstream JIT optimizations.
๐ Quick Start
Installation
dotnet add package Chneau.OpenHours
Usage Example
using Chneau.OpenHours;
// 1. Parse an OSM opening_hours string
var oh = OpenHours.Parse("Mo-Fr 08:00-12:00, 13:00-17:00; Sa 08:00-12:00");
var monday10am = new DateTime(2026, 5, 18, 10, 0, 0, DateTimeKind.Utc);
// 2. Fast point-in-time check (2.0 ns/op)
bool isOpen = oh.IsOpen(monday10am); // true
// 3. Current shift end
DateTime? shiftEnd = oh.GetCurrentShiftEnd(monday10am); // 2026-05-18 12:00:00 UTC
// 4. Time to next open
var tuesdayLunch = new DateTime(2026, 5, 19, 12, 30, 0, DateTimeKind.Utc);
TimeSpan? timeToOpen = oh.GetTimeToOpen(tuesdayLunch); // 00:30:00 (opens at 13:00)
// 5. Find when a 3-hour job can be serviced
TimeSpan? waitFor3h = oh.GetTimeToOpenForDuration(tuesdayLunch, TimeSpan.FromHours(3));
DateTime? whenCanStart = oh.When(tuesdayLunch, TimeSpan.FromHours(3)); // 2026-05-19 13:00:00 UTC
// 6. Next state transitions
var (isOpenNow, durationRemaining) = oh.NextDur(monday10am);
var (_, nextTransitionDate) = oh.NextDate(monday10am); // 2026-05-18 12:00:00 UTC
๐ Benchmark Suite (.NET 10 on AMD Ryzen 9)
| # | Workload | Calls | Latency / Op | Throughput |
|---|---|---|---|---|
| 1 | IsOpen (Rolling timeline) |
100,000 | 2.0 ns | 500,000,000 ops/sec |
| 2 | IsOpen (Pure call) |
1,000,000 | 2.0 ns | 500,000,000 ops/sec |
| 3 | GetTimeToOpen |
10,000 | 8.0 ns | 125,000,000 ops/sec |
| 4 | GetTimeToOpenForDuration |
10,000 | 9.0 ns | 111,000,000 ops/sec |
| 5 | When |
10,000 | 12.0 ns | 83,000,000 ops/sec |
| 6 | NextDur |
10,000 | 67.0 ns | 15,000,000 ops/sec |
| 7 | NextDate |
10,000 | 100.0 ns | 10,000,000 ops/sec |
| 8 | Parse (Cached) |
1,000 | 26.0 ns | 38,000,000 ops/sec |
| 9 | JSON Deserialize |
1,000 | 220 ns | 4,500,000 ops/sec |
| 10 | Stress Test (5,000 unique objects) | 5,000 | 0.50 ยตs/obj | 2,000,000 objs/sec |
๐ ๏ธ Development & Quality Commands
# Run all unit tests
dotnet test
# Run tests in continuous watch mode during development
dotnet watch test
# Run full release build
dotnet build -c Release
๐ License
MIT License. Copyright (c) 2026 chneau.
| Product | Versions 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. |
-
net10.0
- Microsoft.NET.Test.Sdk (>= 17.13.0)
- xunit (>= 2.9.3)
- xunit.runner.visualstudio (>= 3.0.2)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Chneau.OpenHours:
| Package | Downloads |
|---|---|
|
Chneau.TimeTable
Modern, high-performance capacity and schedule constraint evaluation engine in .NET 10. |
GitHub repositories
This package is not used by any popular GitHub repositories.