Welcome to Timerithm, a lightweight Python utility for working with dates, times, durations, and calendar-aware arithmetic.
Timerithm is built on top of Python's standard datetime and timedelta modules while providing a simpler and more expressive interface for common time operations.
Timerithm provides several conveniences:
- Readable duration constructors for microseconds, milliseconds, seconds, minutes, hours, days, and weeks.
- Calendar-aware month and year arithmetic through
months()andyears(). - Automatic month-end correction when shifting dates into shorter months.
- Comparable
Timeobjects supporting equality and chronological comparisons. - Simple date construction through
Time.at(). - Current-time construction through
Time.now(). - Direct date and time component access through properties.
- Custom formatting syntax with predefined layouts and readable formatting tokens.
Timerithm intentionally keeps its implementation small while making common date and time operations easier to express.
It is designed for programmers who want to work with time without repeatedly typing datetime.timedelta(...).
Because apparently writing hours(3) was easier than writing timedelta(hours=3).
Timerithm uses Python's standard library and does not require external dependencies.
Import the required functions and classes from the Timerithm module.
from timerithm import (
Time,
microseconds,
milliseconds,
seconds,
minutes,
hours,
days,
weeks,
months,
years,
)Replace timerithm with the module path used by your installation.
Timerithm is designed to work with standard Python datetime objects and timedelta values.
Timerithm provides helper functions for creating common time durations.
| Function | Description | Underlying Type |
|---|---|---|
microseconds(n) |
Create a duration measured in microseconds. | timedelta |
milliseconds(n) |
Create a duration measured in milliseconds. | timedelta |
seconds(n) |
Create a duration measured in seconds. | timedelta |
minutes(n) |
Create a duration measured in minutes. | timedelta |
hours(n) |
Create a duration measured in hours. | timedelta |
days(n) |
Create a duration measured in days. | timedelta |
weeks(n) |
Create a duration measured in weeks. | timedelta |
Each function accepts an integer amount.
Example:
seconds(30)
minutes(5)
hours(2)
days(7)
weeks(3)These functions return standard Python timedelta objects.
They can therefore be used directly with Time instances.
now = Time.now()
later = now + hours(2)
earlier = now - days(3)Fixed-duration arithmetic follows the behavior of Python's timedelta.
Timerithm provides separate duration types for months and years.
Unlike seconds or days, months and years do not have a fixed duration.
The months() function creates a calendar-month duration.
months(3)The resulting object can be added to or subtracted from a Time instance.
date = Time.at(2026, 1, 15)
result = date + months(3)The resulting date is:
2026-04-15
The years() function creates a calendar-year duration.
years(2)Year arithmetic is internally implemented as twelve-month arithmetic.
date = Time.at(2026, 1, 15)
result = date + years(2)The resulting date is:
2028-01-15
Calendar durations are represented internally by _Months and _Years.
These classes are implementation details and are not intended to be instantiated directly.
The Time class provides the primary interface for working with dates and times in Timerithm.
Each Time instance wraps a Python datetime object.
date = Time.at(2026, 10, 1)The underlying datetime object is stored internally and is used for arithmetic, comparison, formatting, and component access.
Timerithm provides two class methods for constructing Time instances.
Use Time.now() to create a Time instance representing the current local date and time.
current = Time.now()Internally, this uses:
datetime.now()The returned value contains the current year, month, day, hour, minute, second, and microsecond.
Use Time.at() to construct a specific date and time.
date = Time.at(2026, 10, 1)The complete signature is:
Time.at(
year,
month,
day,
hour=0,
minute=0,
second=0,
microsecond=0
)For example:
date = Time.at(
2026,
10,
1,
14,
30,
45,
123456
)This creates a Time object representing:
2026-10-01 14:30:45.123456
Date validation is handled by Python's datetime constructor.
Invalid dates therefore raise the same exceptions produced by datetime.
Timerithm overloads the + and - operators to support intuitive time calculations.
date = Time.at(2026, 10, 1)
date + seconds(30)
date + minutes(15)
date + hours(2)
date + days(7)Each operation returns a new Time object.
The original object is not modified.
For example:
date = Time.at(2026, 10, 1)
future = date + days(5)The values are:
date = 2026-10-01
future = 2026-10-06
Fixed durations can also be subtracted.
date = Time.at(2026, 10, 10)
previous = date - days(5)The resulting date is:
2026-10-05
Timerithm delegates fixed-duration arithmetic to Python's timedelta.
Month arithmetic is handled separately from timedelta arithmetic.
This is necessary because months do not contain a fixed number of days.
date = Time.at(2026, 1, 15)
result = date + months(2)Result:
2026-03-15
Month arithmetic correctly handles changes in year.
date = Time.at(2026, 11, 15)
result = date + months(3)Result:
2027-02-15
Months can also be subtracted.
date = Time.at(2026, 5, 15)
result = date - months(2)Result:
2026-03-15
When shifting a date into a month that does not contain the original day, Timerithm automatically uses the last valid day of the destination month.
For example:
date = Time.at(2026, 1, 31)
result = date + months(1)February does not contain a 31st day.
Timerithm therefore produces:
2026-02-28
Leap years are handled through Python's calendar.monthrange().
date = Time.at(2024, 1, 31)
result = date + months(1)Result:
2024-02-29
The time components are preserved during month arithmetic.
date = Time.at(2026, 1, 31, 14, 30, 45)
result = date + months(1)Result:
2026-02-28 14:30:45
The calendar may change the day.
It does not get to mess with the clock.
Year arithmetic is implemented using month arithmetic.
One year corresponds to twelve calendar months.
date = Time.at(2026, 10, 1)
result = date + years(2)Result:
2028-10-01
date = Time.at(2028, 10, 1)
result = date - years(2)Result:
2026-10-01
Year calculations also inherit the month-end handling behavior of _shift_months().
For example:
date = Time.at(2024, 2, 29)
result = date + years(1)The destination year does not contain February 29.
Timerithm therefore adjusts the result to the final valid day:
2025-02-28
Time objects support equality and chronological comparisons.
The class uses Python's @total_ordering decorator to provide the complete set of ordering operations from __eq__() and __lt__().
| Operator | Description |
|---|---|
== |
Equal timestamps |
!= |
Different timestamps |
< |
Earlier than |
<= |
Earlier than or equal to |
> |
Later than |
>= |
Later than or equal to |
first = Time.at(2026, 1, 1)
second = Time.at(2026, 6, 1)
print(first < second)
print(first == second)
print(second > first)Output:
True
False
True
Time objects can also be compared directly with Python datetime objects.
from datetime import datetime
timerithm_time = Time.at(2026, 1, 1)
python_time = datetime(2026, 1, 1)
print(timerithm_time == python_time)Output:
True
The comparison is performed against the underlying _date value.
Unsupported comparison types return NotImplemented, allowing Python to handle the operation according to its normal comparison rules.
Time implements __hash__() using the wrapped datetime.
This allows Time instances to be used in hash-based collections such as sets and dictionaries.
Example:
date = Time.at(2026, 1, 1)
dates = {date}
print(date in dates)Output:
True
Two Time instances representing the same underlying datetime produce equivalent hash behavior.
Because time apparently needed to become hashable too.
Timerithm exposes individual components of the underlying datetime through read-only properties.
| Property | Description |
|---|---|
microsecond |
Microsecond component. |
millisecond |
Millisecond component. |
second |
Second component. |
minute |
Minute component. |
hour |
Hour component. |
day |
Day of the month. |
month |
Month number. |
year |
Year number. |
date = Time.at(
2026,
10,
1,
14,
30,
45,
123456
)
print(date.year)
print(date.month)
print(date.day)
print(date.hour)
print(date.minute)
print(date.second)
print(date.millisecond)
print(date.microsecond)Output:
2026
10
1
14
30
45
123
123456
The millisecond property is derived from the underlying microsecond value:
self._date.microsecond // 1000Therefore:
123456 microseconds
becomes:
123 milliseconds
The remaining fractional precision is discarded.
Timerithm provides custom date and time formatting through the format() method.
date.format(layout)The formatter supports:
- Predefined layouts.
- Custom formatting tokens.
- Fractional seconds.
- 12-hour and 24-hour clocks.
- Weekday names.
- Month names.
- AM/PM formatting.
Example:
date = Time.at(2026, 10, 1, 14, 30, 45)
print(date.format("T"))Output:
2026-10-01 14:30:45
Timerithm provides several predefined layout shortcuts.
| Preset | Expansion | Example |
|---|---|---|
S |
BBBB D, YYYY hh:mm |
October 1, 2026 14:30 |
E |
D BBBB, YYYY hh:mm |
1 October, 2026 14:30 |
L |
YYYYMMDDhhmmss |
20261001143045 |
T |
YYYY-MM-DD hh:mm:ss |
2026-10-01 14:30:45 |
C |
AAAA, BBBB D YYYY hh:mm:ss |
Thursday, October 1 2026 14:30:45 |
date = Time.at(2026, 10, 1, 14, 30, 45)
print(date.format("S"))
print(date.format("E"))
print(date.format("L"))
print(date.format("T"))
print(date.format("C"))The preset is expanded before the final strftime() operation.
Timerithm supports readable formatting tokens that are converted into Python strftime directives.
| Token | Description |
|---|---|
AAAA |
Full weekday name |
AAA |
Abbreviated weekday name |
BBBB |
Full month name |
BBB |
Abbreviated month name |
YYYY |
Four-digit year |
YY |
Two-digit year |
MM |
Zero-padded month |
DD |
Zero-padded day |
hh |
24-hour clock hour |
ii |
12-hour clock hour |
mm |
Minute |
ss |
Second |
F |
Microseconds |
J |
Day of the year |
U |
ISO weekday number |
W |
Weekday number |
P |
AM/PM |
p |
Lowercase AM/PM |
date = Time.at(2026, 10, 1, 14, 30, 45)
print(date.format("AAAA, BBBB D YYYY"))Example output:
Thursday, October 1 2026
Another example:
print(date.format("ii:mm p"))Output:
02:30 pm
Timerithm provides special handling for D and M.
The D token represents the numerical day of the month without zero-padding.
The M token represents the numerical month without zero-padding.
For example:
date = Time.at(2026, 3, 5)
print(date.format("M/D/YYYY"))Output:
3/5/2026
This differs from:
date.format("MM/DD/YYYY")which produces:
03/05/2026
This distinction allows both padded and unpadded calendar representations.
Timerithm supports repeated f characters for formatting fractional seconds.
The number of f characters determines how many digits of the microsecond component are included.
date = Time.at(
2026,
10,
1,
14,
30,
45,
123456
)date.format("hh:mm:ss.f")Output:
14:30:45.1
date.format("hh:mm:ss.fff")Output:
14:30:45.123
date.format("hh:mm:ss.ffffff")Output:
14:30:45.123456
Timerithm truncates the microsecond string to the requested number of digits.
The maximum meaningful precision is six digits because Python's datetime stores microseconds.
The formatter supports both uppercase and lowercase AM/PM output.
Using:
P
produces the standard AM or PM representation.
Using:
p
produces lowercase am or pm.
Example:
date = Time.at(2026, 10, 1, 14, 30)
print(date.format("ii:mm P"))
print(date.format("ii:mm p"))Output:
02:30 PM
02:30 pm
The lowercase form is implemented by replacing AM and PM after strftime() formatting.
The following example demonstrates the primary features of Timerithm.
from timerithm import (
Time,
hours,
days,
months,
years,
)
# Create a starting date
start = Time.at(
2024,
1,
31,
12,
30,
45
)
# Perform fixed-duration arithmetic
later = start + hours(5)
next_week = start + days(7)
# Perform calendar arithmetic
next_month = start + months(1)
next_year = start + years(1)
# Compare dates
print(next_month > start)
# Inspect components
print(next_month.year)
print(next_month.month)
print(next_month.day)
# Format results
print(start.format("C"))
print(later.format("T"))
print(next_month.format("YYYY-MM-DD"))
print(next_year.format("S"))True
2024
2
29
Wednesday, January 31 2024 12:30:45
2024-01-31 17:30:45
2024-02-29
January 31, 2025 12:30
The example demonstrates:
- Explicit time construction.
- Fixed-duration arithmetic.
- Calendar-aware month arithmetic.
- Calendar-aware year arithmetic.
- Date comparison.
- Component inspection.
- Custom formatting.
- Automatic leap-year handling.
Timerithm is designed as a lightweight abstraction over Python's existing date and time functionality.
Rather than replacing datetime, it builds on top of it.
The library separates fixed durations from calendar durations:
timedeltahandles microseconds through weeks._Monthshandles calendar-month arithmetic._Yearsrepresents calendar years through twelve-month shifts.
This distinction allows Timerithm to provide intuitive month and year arithmetic without pretending that every month contains the same number of days.
The Time class keeps the underlying datetime available internally while providing:
- Simple construction.
- Operator-based arithmetic.
- Direct comparison.
- Component properties.
- Custom formatting.
Timerithm is intentionally compact and relies heavily on Python's standard library rather than implementing another independent date/time system.
The goal is not to reinvent time.
Time has already done enough damage.
microseconds(amount)
milliseconds(amount)
seconds(amount)
minutes(amount)
hours(amount)
days(amount)
weeks(amount)
months(amount)
years(amount)Time(date)Time.now()
Time.at(
year,
month,
day,
hour=0,
minute=0,
second=0,
microsecond=0
)time + timedelta
time - timedelta
time + months(n)
time - months(n)
time + years(n)
time - years(n)time == other
time != other
time < other
time <= other
time > other
time >= othertime.microsecond
time.millisecond
time.second
time.minute
time.hour
time.day
time.month
time.yeartime.format(layout)Timerithm intentionally remains a small wrapper around Python's standard date/time facilities.
The current implementation does not provide:
- Time zone management.
- Time zone conversion.
- Daylight-saving-time utilities.
- Relative date parsing.
- Natural-language date parsing.
- Duration multiplication or division.
- Custom locale management.
- Serialization helpers.
- A custom
__str__()or__repr__()representation.
The current __str__() and __repr__() methods are placeholders and return:
not implemented
and:
<not implemented>
respectively.
These are implementation placeholders rather than formatted representations of the underlying date.
Timerithm is distributed according to the license included with the project.
See the project's license file for the applicable terms.
A compact Timerithm program can therefore look like this:
from timerithm import Time, months, days
date = Time.at(2026, 1, 31)
future = date + months(1) + days(7)
print(future.format("C"))Output:
Saturday, March 7 2026 00:00:00
A small interface for doing the things calendars have spent centuries making unnecessarily complicated.