Skip to content

QuotaPeriodCalculator

Namespace AgentPrism · Assembly AgentPrism.Core.dll

Calculates which quota period an instant falls into, and when that period resets.

public static class QuotaPeriodCalculator

objectQuotaPeriodCalculator

object.GetType(), object.MemberwiseClone(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()

Pure logic: it holds no state and reads no clock. This lets a unit test exercise day and month boundaries, daylight-saving transitions, and month ends without depending on real time.

The period boundary is calculated in the local time zone, not UTC. An admin who says “daily quota” means their own business day; resetting by UTC would reset a UTC+03 tenant’s counter three hours early, before noon.

GetAllPeriodStarts(DateTimeOffset, TimeZoneInfo)

Section titled “ GetAllPeriodStarts(DateTimeOffset, TimeZoneInfo)”

Calculates the start of every period a rule set touches.

public static IReadOnlyDictionary<QuotaPeriod, DateOnly> GetAllPeriodStarts(DateTimeOffset instant, TimeZoneInfo timeZone)

instant DateTimeOffset

The instant.

timeZone TimeZoneInfo

The time zone.

IReadOnlyDictionary<QuotaPeriod, DateOnly>

The first day of the period, for each period interval.

Consumption is written to both period counters: a tenant can define both a daily and a monthly quota at the same time, and the two are counted independently.

ArgumentNullException

timeZone is null.

GetPeriodEnd(DateTimeOffset, QuotaPeriod, TimeZoneInfo)

Section titled “ GetPeriodEnd(DateTimeOffset, QuotaPeriod, TimeZoneInfo)”

Finds when the period an instant falls into will reset.

public static DateTimeOffset GetPeriodEnd(DateTimeOffset instant, QuotaPeriod period, TimeZoneInfo timeZone)

instant DateTimeOffset

The instant.

period QuotaPeriod

The period interval.

timeZone TimeZoneInfo

The time zone the period boundary is calculated in.

DateTimeOffset

The instant the next period starts (UTC).

The returned value is reflected to the client as “when it resets” in Retry-After and in ProblemDetails.

ArgumentNullException

timeZone is null.

GetPeriodStart(DateTimeOffset, QuotaPeriod, TimeZoneInfo)

Section titled “ GetPeriodStart(DateTimeOffset, QuotaPeriod, TimeZoneInfo)”

Finds the first day of the period an instant falls into.

public static DateOnly GetPeriodStart(DateTimeOffset instant, QuotaPeriod period, TimeZoneInfo timeZone)

instant DateTimeOffset

The instant (UTC or another offset).

period QuotaPeriod

The period interval.

timeZone TimeZoneInfo

The time zone the period boundary is calculated in.

DateOnly

The first day of the period, in the local calendar.

ArgumentNullException

timeZone is null.

Converts a period start into midnight in that time zone.

public static DateTimeOffset ToUtcInstant(DateOnly date, TimeZoneInfo timeZone)

date DateOnly

The first day of the period (local calendar).

timeZone TimeZoneInfo

The time zone.

DateTimeOffset

The UTC equivalent of local midnight.

During a daylight-saving transition, local midnight may not exist (spring forward) or may be valid twice (fall back). A time that does not exist is moved to right after the transition; for an ambiguous time, the earlier offset is chosen. Both are defined behavior instead of silently producing a wrong result.

ArgumentNullException

timeZone is null.