Skip to main content

Metric Calendar date conversion — a rational decimal calendar system

Project description

metric_calendar

A Python library for the Metric Calendar — a rational decimal calendar system built on the March equinox.

The Metric Calendar divides the solar year into 12 months of exactly 30 days each, organised into 10-day weeks. The year begins at the vernal equinox (March 20) with three intercalary Turning days, and includes two or three Yule days at midsummer to keep the calendar aligned with the solar year. Every date is fully deterministic from standard Gregorian input.

Installation

pip install metric_calendar

Requires Python 3.8 or later. No external dependencies.

Quick Start

import datetime
from metric_calendar import today, gregorian_to_metric, metric_to_gregorian

# Get today's Metric date
md = today()
print(md.month_name, md.day, md.year)  # e.g. "Unil 1 56"

# Convert a specific Gregorian date
md = gregorian_to_metric(datetime.date(2026, 3, 23))
print(md)
# MetricDate(year=56, month=1, month_name='Unil', day=1, week_day=1,
#            day_name='Primday', week=1, season_index=0, ...)

# Convert back to Gregorian
d = metric_to_gregorian(56, 'month', 1, 1)
print(d)  # 2026-03-23

Calendar Structure

The Metric Calendar year starts at the March equinox (March 20) and is structured as follows:

Period Days Notes
The Turning 3 Vigil, Balance, Dawn — year-opening intercalary days
Months 1–9 (Unil–Novil) 270 9 months × 30 days
Yule 2–3 Yule Eve, Midwinter, and Kindling (leap years only)
Months 10–12 (Decil–Duodecil) 90 3 months × 30 days

Each month contains three 10-day weeks. Days 8, 9, and 10 of each week (Octday, Novday, Decday) are rest days.

Metric year epoch: Year 0 = 1970 CE. Year 56 spans March 2026 – March 2027.

Month Names

# Name # Name
1 Unil 7 Septil
2 Duil 8 Octil
3 Tril 9 Novil
4 Quadril 10 Decil
5 Quintil 11 Undecil
6 Sextil 12 Duodecil

Day Names

# Name Rest?
1 Primday
2 Duoday
3 Triday
4 Quadday
5 Quintday
6 Hexday
7 Septday
8 Octday rest
9 Novday rest
10 Decday rest

Special Days

Name Description
Vigil First Turning day (March 20)
Balance Second Turning day (March 21)
Dawn Third Turning day (March 22)
Yule Eve First Yule day
Midwinter Second Yule day
Kindling Third Yule day (leap years only)
Midsummer Quadril 1 — first day of the fourth month
Spiral Quintil 18 — golden-ratio day of the year

API Reference

gregorian_to_metric(date: datetime.date) -> MetricDate

Convert a Gregorian datetime.date to a MetricDate.

import datetime
from metric_calendar import gregorian_to_metric

md = gregorian_to_metric(datetime.date(2026, 6, 21))
print(md.is_midsummer)   # True
print(md.month_name)     # 'Quadril'
print(md.day)            # 1

metric_to_gregorian(year, period_type, period_value, day_of_month=1) -> datetime.date

Convert a Metric Calendar date back to a Gregorian datetime.date.

Parameters:

  • year — Metric year (0 = 1970 CE)
  • period_type — one of 'turning', 'month', or 'yule'
  • period_value:
    • 'turning': 0 (Vigil), 1 (Balance), 2 (Dawn)
    • 'month': month number 112
    • 'yule': 0 (Yule Eve), 1 (Midwinter), 2 (Kindling, leap years only)
  • day_of_month — day within the month, 130 (only used when period_type='month')
from metric_calendar import metric_to_gregorian

# Unil 1, Year 56
metric_to_gregorian(56, 'month', 1, 1)       # datetime.date(2026, 3, 23)

# The Turning — Vigil, Year 56
metric_to_gregorian(56, 'turning', 0)         # datetime.date(2026, 3, 20)

# Yule Eve, Year 56
metric_to_gregorian(56, 'yule', 0)            # datetime.date(2026, 12, 18)

is_rest_day(date: datetime.date) -> bool

Return True if the given Gregorian date falls on a Metric rest day (Octday, Novday, or Decday).

from metric_calendar import is_rest_day
import datetime

is_rest_day(datetime.date(2026, 4, 1))   # True  — Decday
is_rest_day(datetime.date(2026, 3, 23))  # False — Primday

today() -> MetricDate

Return today's date as a MetricDate.

from metric_calendar import today

md = today()
print(f"{md.day_name}, {md.month_name} {md.day}, Year {md.year}")

MetricDate

An immutable dataclass with the following fields:

Field Type Description
year int Metric year (epoch 1970)
month int Month number 1–12; 0 for Turning/Yule days
month_name str e.g. 'Unil'; empty for Turning/Yule days
day int Day of month 1–30; 0 for Turning/Yule days
week_day int Day of week 1–10; 0 for Turning/Yule days
day_name str e.g. 'Primday'; empty for Turning/Yule days
week int Week of year 1–36; 0 for Turning/Yule days
season_index int Season 0–3 (Spring/Summer/Autumn/Winter); -1 for Turning/Yule days
is_leap_year bool Whether this Metric year has a Kindling day
is_turning bool True for Vigil, Balance, or Dawn
is_yule bool True for Yule Eve, Midwinter, or Kindling
is_midsummer bool True on Quadril 1
is_spiral bool True on Quintil 18 (golden-ratio day)
is_rest bool True when week_day >= 8
special_day str Name of the special day, or empty string

Running the Tests

python -m pytest tests/
# or
python -m unittest discover tests/

License

MIT. See metricweek.com for the full calendar specification.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

metric_calendar-1.0.0.tar.gz (5.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

metric_calendar-1.0.0-py3-none-any.whl (5.2 kB view details)

Uploaded Python 3

File details

Details for the file metric_calendar-1.0.0.tar.gz.

File metadata

  • Download URL: metric_calendar-1.0.0.tar.gz
  • Upload date:
  • Size: 5.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for metric_calendar-1.0.0.tar.gz
Algorithm Hash digest
SHA256 e7622ff37ee068e99f4f9a87d6e2d08c567cf370f797c31e812d70b8c31b1125
MD5 157e55010987cab59a7c4e6ca1d87531
BLAKE2b-256 002689dc062c22bef990774b3935b3279c16e52c1b69dc554c79ef1f55cd7907

See more details on using hashes here.

Provenance

The following attestation bundles were made for metric_calendar-1.0.0.tar.gz:

Publisher: publish-python.yml on alexrabarts/metric-calendar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file metric_calendar-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for metric_calendar-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 666e8001c6fb0bc6e50dc2bbddc97c4c6805fe831427047ad544d587717d0d1e
MD5 cd56528656feba0d6aa397149cdfe755
BLAKE2b-256 3d9d17353cf6d9d8a22b89d3b1d72b08741f106b452db45775e053cdd8d2d1ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for metric_calendar-1.0.0-py3-none-any.whl:

Publisher: publish-python.yml on alexrabarts/metric-calendar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page