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.1.tar.gz (6.5 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.1-py3-none-any.whl (5.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: metric_calendar-1.0.1.tar.gz
  • Upload date:
  • Size: 6.5 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.1.tar.gz
Algorithm Hash digest
SHA256 c7594324681b2a0ebc642791728070e389e99eabcf4f293c92d545fa7ae6bee8
MD5 f341b9299055703e439b2beb1f969c88
BLAKE2b-256 95922d9237d8072842a1ae17d3b028b25ef625d086841a3327f1ab2d82b36d26

See more details on using hashes here.

Provenance

The following attestation bundles were made for metric_calendar-1.0.1.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.1-py3-none-any.whl.

File metadata

File hashes

Hashes for metric_calendar-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 76c4aaa6ed7e2ca347b49dd8ef89a8b03f7b8c93f6f05d304b96da160203c0d0
MD5 bfdd89f27958566db3f7f7abf3520142
BLAKE2b-256 a3263038c7f283324d78918c1b305de3b6a20379c89ef9faab133e058b222f5a

See more details on using hashes here.

Provenance

The following attestation bundles were made for metric_calendar-1.0.1-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