Table of Contents

Bodu.Globalization.Calendar.Algorithms Namespace

Bodu.Globalization.Calendar.Algorithms

Bodu.Globalization.Calendar.Algorithms

Purpose

Bodu.Globalization.Calendar.Algorithms is the date-calculation layer of Bodu.Globalization.Calendar. It defines the strategy a rule uses to find its nominal date for a year, and the contract and registry for plugging in custom calculators.

Every NotableDateRule carries exactly one occurrence source: an IDateCalculationStrategy (13 single-date strategies) or an IDateRecurrenceStrategy (four frequency-based recurrence sources). The loader maps each <Strategy> (or <Recurrence>) element in a rule document to one of these built-in strategies; you rarely construct them by hand, but they are the public vocabulary the engine resolves against. The most common are listed below - the strategy reference covers the full catalogue.

Static documentation

Key types

The strategy contract and built-in strategies

Algorithm keys

AlgorithmDateStrategy resolves a string key to a bundled astronomical / gazetted calculator. Built-in keys include western-easter and orthodox-easter (exposed as the WesternEasterKey / OrthodoxEasterKey constants), vernal-equinox, autumnal-equinox, jp-vernal-equinox, jp-autumnal-equinox, qingming, vesak, asalha-puja, losar, matariki, and the Hindu-festival keys (diwali, holi, maha-shivaratri, ganesh-chaturthi, …). AlgorithmDateStrategy.IsKnownKey(key) reports whether a key is built in. The calculators that back these keys are an internal implementation detail reached only through the key.

Custom algorithms

  • INotableDateAlgorithm - DateOnly? Calculate(int year). Implement this to add a calculator (returning null for years you do not support).
  • INotableDateAlgorithmRegistry, NotableDateAlgorithmRegistry - the lookup and its chainable, mutable implementation (Register(key, algorithm)). Keys not recognised by AlgorithmDateStrategy fall through to this registry, so a custom key registered here can be referenced from a rule as <Algorithm key="my-key" />. Pass the registry to NotableDateResourceLoader.Load(xml, resolver, registry) (to whitelist the key during validation) and to the service through NotableDateServiceOptions.Algorithms - new NotableDateService(resource, new NotableDateServiceOptions { Algorithms = registry }).
  • StrategyResolutionContext - the per-resolution context passed to strategies; resolves referenced rules (ResolveReference) cycle-safely and carries the custom algorithm registry.

Minimal sample

using Bodu.Globalization.Calendar;
using Bodu.Globalization.Calendar.Algorithms;

// A custom calculator …
public sealed class PiDayAlgorithm : INotableDateAlgorithm
{
    public DateOnly? Calculate(int year) => new DateOnly(year, 3, 14);
}

// … registered under a key the rule document references via <Algorithm key="pi-day" />.
var registry = new NotableDateAlgorithmRegistry().Register("pi-day", new PiDayAlgorithm());

NotableDateResource resource = NotableDateResourceLoader.Load(xml, _ => null, registry);
NotableDateService service   = new NotableDateService(resource, new NotableDateServiceOptions { Algorithms = registry });

Classes

AlgorithmDateStrategy

Calculates a notable date using a named, algorithm-backed computation such as Easter, an equinox, a lunar-phase festival, or a gazetted date table.

DailyIntervalRecurrenceStrategy

Generates an occurrence every fixed number of calendar days from an anchor date, such as every 14 days from 1 January 2026.

DayOfWeekInMonthStrategy

Calculates a notable date that falls on the nth (or last) occurrence of a weekday within a month, such as the fourth Thursday of November or the last Monday of May.

DayOfYearStrategy

Calculates a date by its ordinal position within a Gregorian year, such as the 100th day or the final day of the year.

FixedDateStrategy

Calculates a notable date that falls on a fixed month and day every year, optionally expressed in a non-Gregorian calendar system such as the Islamic, Hebrew, Persian, or Chinese lunisolar calendar.

IsoWeekDateStrategy

Calculates a weekday within an ISO-8601 week of an ISO week-year, such as the Monday of ISO week 1 or the Friday of ISO week 20.

MonthlyDayRecurrenceStrategy

Generates an occurrence on a specified calendar day every fixed number of months, such as the 15th of every month or the 20th of every third month.

MonthlyWeekdayRecurrenceStrategy

Generates an ordinal weekday every fixed number of months, such as the first Monday of every month or the last Friday of every third month.

NotableDateAlgorithmRegistry

A mutable registry of custom INotableDateAlgorithm implementations keyed by algorithm key.

NthWeekdayFromRuleStrategy

Calculates the Nth occurrence of a weekday strictly before or strictly after another rule's occurrence, such as the second Monday after a festival.

OffsetFromRuleStrategy

Calculates a notable date as a fixed day offset from another rule's occurrence, such as Good Friday two days before Easter Sunday.

OrdinalDayOfMonthStrategy

Calculates a day by its ordinal position from the beginning or end of a Gregorian month, such as the last day of February or the second-last day of a month.

RelativeWeekdayInMonthStrategy

Calculates a notable date that falls on a weekday relative to an anchor weekday occurrence within a month, such as the Tuesday after the first Monday of November (United States general election day).

StrategyResolutionContext

Provides a strategy with access to the surrounding resource so that referential strategies (such as OffsetFromRuleStrategy) can resolve the occurrence of another rule for the same year.

WeekdayNearDateStrategy

Calculates a notable date that falls on a weekday on, before, after, or nearest to a fixed month and day, such as the Monday on or after 24 May.

WeekdayNearRuleStrategy

Calculates a weekday on, before, after, or nearest to the date produced by another rule, such as the first Monday after Easter Sunday.

WeeklyRecurrenceStrategy

Generates occurrences on one or more selected weekdays every fixed number of weeks, such as every Monday and Friday or every second Tuesday.

WorkingDayInMonthStrategy

Calculates the Nth working day from the beginning or end of a Gregorian month, such as the first working day of January or the last working day of a reporting month.

WorkingDayOffsetFromRuleStrategy

Calculates a date a specified number of working days before or after another rule's occurrence, such as the last working day before a public-holiday shutdown.

Interfaces

IDateCalculationStrategy

Defines the calculation contract for a single rule strategy: given a Gregorian year, produce the occurrence of the notable date in that year, if any.

IDateRecurrenceStrategy

Calculates every occurrence of a recurring notable-date pattern that falls within a bounded date range, such as every second Tuesday or the last Friday of every month.

INotableDateAlgorithm

Computes the date of a notable date for a Gregorian year from a closed-form or tabular algorithm. Implementations are registered under a key and dispatched by the AlgorithmDateStrategy when a rule references that key, allowing the algorithm catalogue to be extended beyond the built-in computations.

INotableDateAlgorithmRegistry

Provides lookup of custom INotableDateAlgorithm implementations by key, supplementing the engine's built-in algorithm catalogue.

Enums

InvalidDayOfMonthBehavior

Specifies how a monthly day-of-month recurrence handles a month that does not contain the requested day, such as the 31st in February.