dev.almanack/almanack
name:dev.almanack/almanack
Date math and SVG rendering for fictional and custom calendars. Exact, stateless and deterministic.
- transport:
- remote
- credential class:
- self-provisionable
Owner verification
Not yet verified. Verifying proves you control this server and is free, permanently — it never changes a published score.
Start verification →Tools
- add_to_dateshallow
Move a date by years, months and days. They are applied in that fixed order, which matters: a month then a day is not always the same landing as a day then a month. Adding days is always exact. policy decides what happens when the day does not exist in the target month: 'clamp' (default) moves to that month's last day, 'reject' refuses with an error, 'spill' carries the excess into the following month. Adding months to an intercalary date is refused, because those days sit between months; add days instead.
- calendar_eventsshallow
When a recurring event falls. query 'next' gives the first occurrence after the date in 'after' (or on it when inclusive is true). query 'occurrences' gives every occurrence between start and end inclusive, capped at limit and at most 1000; 'truncated' says whether the list was cut short, so never read a truncated list as complete. The event is either a name the calendar defines or an event given inline: {'name':..,'type':'fixed','month':..,'day':..}, {'name':..,'type':'nth_weekday','month':..,'weekday':..,'n':..} or {'name':..,'type':'interval','anchor':{..},'every':N,'unit':'days'|'years'}. A year in which the event's date does not exist produces no occurrence: a leap-day feast happens in leap years and not otherwise, and is never moved to a nearby day.
- calendar_weekdayshallow
Which weekday a date falls on, as a 0-based index into the calendar's own week plus its name. Exact; never estimates. Returns weekday null when the date is an intercalary day the week does not count: those days sit outside the cycle and the week resumes after them exactly where it left off. Fails if the calendar defines no week rather than inventing a seven-day one.
- convert_dateshallow
Convert between a calendar date, its day number, and its Gregorian date. Give exactly one of date, day_number or gregorian; all three come back, with whether the year is a leap year and how long it is. Exact arithmetic; never estimates. A date that does not exist in this calendar is refused with the real range, never rounded to a nearby day.
- date_intervalshallow
The distance between two dates. 'days' is the exact signed count (negative when end precedes start) and is always reliable. 'calendar' breaks the same distance into whole years, then whole months, then days, using the clamp policy, so adding that breakdown back to the start date with add_to_date returns the end date exactly. Exact integer arithmetic; never estimates.
- format_calendar_dateshallow
Write a date out to a pattern. pattern is either a name from the calendar's own 'formats' (names win) or a pattern written out. Tokens: {day} {day-name} {month} {month-name} {year} {era} {era-abbr} {era-year} {intercalary}, with an optional zero-pad width on the numeric ones as {day:2}. Write a literal brace as {{ or }}. The output is exactly reversible by parse_calendar_date with the same pattern, so use these two as a pair.
- moon_phasesshallow
Every moon's phase on a date. 'fraction' is the exact position in the cycle, 0.0 at new and 0.5 at full, and is the number to compute with. 'phase' is only which named bucket that fraction falls in, and 'illumination' is the lit portion of the disc from 0.0 to 1.0. Computed in closed form from the moon's period and offset, not simulated and not astronomical: it is exactly what the spec describes. Measured at the start of the day; pass day_fraction 0.5 for midday.
- nth_weekday_of_monthshallow
The nth given weekday of a month: the 3rd Tuesday, the last Friday. n is 1-based from the start of the month, or negative from the end (-1 is the last). Only days the week counts are considered. If the month has no such day the call fails naming how many there are; it never returns the nearest one instead. Exact; never estimates.
- parse_calendar_dateshallow
Read a written date back into a date. Strict, with no fuzzy matching of any kind: literal characters must match character for character, month, weekday and era names must be names this calendar actually defines, and a weekday written into the string must be the weekday that date really falls on. A string that does not fit is an error naming what did not fit; it never returns a best guess. Use the same pattern that wrote the string.
- render_calendar_pageshallow
Draw one month of a calendar as an SVG grid and return the SVG itself. Columns come from the calendar's own week, so a ten-day week gets ten columns. Intercalary days belong to no month and never take a cell in the grid: the blocks either side of this month are drawn as a strip outside it, dashed when the week does not count them. Moons get a glyph per day, lit to that moon's phase, when the calendar defines any. Events use the same shape as render_timeline and are filtered to the days on this page, with at most 500 given and at most three shown per day before the rest become a count. Colours are assigned per color_key from the whole list before filtering, so a category keeps its colour across months. Fully deterministic: the same arguments always produce byte-identical SVG. The output is static SVG and never contains script or style.
- render_timelineshallow
Draw a date range as a horizontal SVG timeline and return the SVG itself. Both ends of the range are included. Axis ticks choose their own granularity from the span — days, months or years — and year labels use the calendar's eras where it defines them, so a range crossing a descending era's boundary counts down to it and up again after it, ... 3, 2, 1 | 1, 2, 3 ... Era boundaries inside the range are drawn as labelled vertical rules. Each event is {'label':.., 'date':{..}} for a marker or {'label':.., 'start':{..}, 'end':{..}} for a bar, optionally with 'lane' (a row name) and 'color_key' (a category name picking an accent colour). AT MOST 500 EVENTS: more is refused with render.timeline.too_many_events rather than drawn partially. Labels never overlap; they stagger and then truncate with an ellipsis, and the full label is always in the marker's <title> whatever ends up drawn. theme is 'default', 'dark', or a theme object with all of font_family, background, axis, text and accents; colours must be #RGB or #RRGGBB and anything else is refused. Fully deterministic: the same arguments always produce byte-identical SVG, with no timestamps or generated ids in it. The output is static SVG and never contains script or style.
- scatter_datesshallow
Scatter a number of dates across a span, for generating events. The seed is required and the draw is fully deterministic: the same calendar, span, count, seed and unique flag always give the same dates, on any machine. unique=true (default) draws without repeats and fails if count exceeds the number of days in the span. Results come back sorted.
- validate_calendar_specshallow
Check a calendar spec and list everything wrong with it. Returns structured errors and warnings; it never throws and never partially accepts a spec. Errors mean the spec is unusable; warnings mean it is legal but probably not what was meant (a leap rule that changes no year's length, a moon that cycles every few hours). Use this before any other tool when you have written or edited a spec yourself. It is the only tool that accepts a malformed spec.
Embed this server’s score
Tool count and median score across every tool in this server’s corpus — honest in a way a single cherry-picked tool’s badge wouldn’t be.
[](https://vouch.tools/servers/4e9740f0-315c-4a63-91c3-c86978157488)