Skip to main content

Add and subtract HH:MM[:SS] time strings in Python — durations, aggregation, and timedelta integration.

Project description

hmscalc

PyPI version Python versions CI License: MIT

Add and subtract HH:MM / HH:MM:SS time strings in Python — no manual conversion to seconds required.

Quick Start

pip install hmscalc
from hmscalc import HMSTime

a = HMSTime("1:30:15")
b = HMSTime("2:15:45")

print(a + b)   # "3:46:00"
print(a - b)   # "-0:45:30"
print(a * 2)   # "3:00:30"
print(a / 2)   # "0:45:07"

Why hmscalc?

Approach Limitation
datetime.timedelta No "1:30:15" string parsing out of the box
Manual seconds math Verbose; easy to mishandle negative values
pytimeparse Parse-only — arithmetic is still on you
hmscalc Parse and add / subtract / aggregate in one API

Features

  • Addition, subtraction, and scalar multiply/divide
  • Sum, average, min, and max of multiple values
  • HH:MM and HH:MM:SS input (hours may exceed 24 — duration model)
  • Negative durations, comparison operators, datetime.timedelta integration
  • Input whitespace trimming (" 1:30:15 ")
  • Type hints with py.typed marker
  • Python 3.9 through 3.14
  • CLI: hmscalc add / sub / sum from the terminal

CLI

After pip install hmscalc:

hmscalc add 1:30 2:15 0:45
# 4:30:00

hmscalc sub 2:00 0:45
# 1:15:00

hmscalc sum 1:00 2:00 3:00
# 6:00:00

Equivalent: python -m hmscalc add 1:00 2:00

Usage

Import

from hmscalc import HMSTime

Creating HMSTime (string vs seconds vs timedelta)

Input Recommended API Example
"1:30:15" string HMSTime("1:30:15") Human-readable durations
Integer seconds HMSTime.from_seconds(3661) Programmatic / computed values
datetime.timedelta HMSTime.from_timedelta(delta) Interop with stdlib datetime

HMSTime(...) accepts strings only. Use from_seconds() for numeric seconds (TypeError if not int).

Basic Operations

a = HMSTime("1:30:15")
b = HMSTime("2:15:45")

print(a + b)            # "3:46:00"
print(a - b)            # "-0:45:30"
print(a > b)            # False
print(a.to_seconds())   # 5415
print(a.to_tuple())     # (1, 30, 15)
print(a.to_dict())      # {'hh': 1, 'mm': 30, 'ss': 15, 'negative': False}

Scalar Operations

HMSTime("1:00:00") * 3    # "3:00:00"
HMSTime("1:30:00") / 2    # "0:45:00"
2 * HMSTime("0:30:00")    # "1:00:00"

Aggregation

times = [HMSTime("1:30:15"), HMSTime("2:15:45"), HMSTime("0:45:30")]

HMSTime.sum(times)      # "4:31:30"
HMSTime.average(times)  # "1:30:30"
HMSTime.min(times)      # "0:45:30"
HMSTime.max(times)      # "2:15:45"

Work Time Example

work_sessions = [
    HMSTime("2:15:30"),
    HMSTime("1:45:00"),
    HMSTime("0:30:15"),
]
print(HMSTime.sum(work_sessions))  # "4:30:45"

timedelta Integration

import datetime

t = HMSTime("1:30:15")
delta = t.to_timedelta()
restored = HMSTime.from_timedelta(delta)  # HMSTime("1:30:15")

Error Handling

from hmscalc import InvalidTimeFormatError, NotTimeStringError

HMSTime(" 1:30:15 ")   # OK — whitespace trimmed
HMSTime("1:99:00")     # InvalidTimeFormatError
HMSTime(123)             # NotTimeStringError

Negative Values

t = HMSTime("-1:00:00")
print(str(t))           # "-1:00:00"
print(t.is_negative)    # True
print(t.to_seconds())   # -3600
print(t.to_dict())      # {'hh': 1, 'mm': 0, 'ss': 0, 'negative': True}

to_tuple() returns absolute (hh, mm, ss); use is_negative or to_seconds() for sign.

Hashable (sets and dict keys)

a = HMSTime("1:00:00")
b = HMSTime("2:00:00")
sessions = {a, b, a}  # 2 unique items

API Reference

HMSTime(time_str: str)

Parse HH:MM or HH:MM:SS. Whitespace is trimmed. Hours may exceed 24 (duration model).

Class methods

Method Description
HMSTime.from_seconds(total_seconds: int) Build from integer seconds
HMSTime.from_timedelta(delta) Build from datetime.timedelta
HMSTime.sum(times) Sum iterable; empty → "0:00:00"
HMSTime.average(times) Mean, rounded to nearest second
HMSTime.min(times) / HMSTime.max(times) Min / max of iterable

Instance methods & properties

Member Description
is_negative True if total seconds < 0
to_seconds() Integer total seconds (signed)
to_minutes() / to_hours() Float conversion
to_timedelta() datetime.timedelta
to_tuple() (hh, mm, ss) absolute components
to_dict() {'hh', 'mm', 'ss', 'negative'}

Operators

+, -, *, / (scalar), ==, !=, <, <=, >, >=

Exceptions

from hmscalc import HMSTimeError, InvalidTimeFormatError, NotTimeStringError
Exception When
InvalidTimeFormatError Bad format, mm/ss ≥ 60, empty string
NotTimeStringError Non-string input
HMSTimeError Base class for both

Input Rules

  • Formats: HH:MM or HH:MM:SS
  • Minutes and seconds: 0–59
  • Optional leading - for negative durations
  • Surrounding whitespace is ignored

Development

See CONTRIBUTING.md for branching, CI, and release process.

poetry install
poetry run pytest --cov=hmscalc

Docker matrix (Python 3.9–3.14): docker build -t hmscalc . && docker run --rm hmscalc ./runtests.sh

Links

License

MIT License

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

hmscalc-0.6.0.tar.gz (7.8 kB view details)

Uploaded Source

Built Distribution

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

hmscalc-0.6.0-py3-none-any.whl (9.5 kB view details)

Uploaded Python 3

File details

Details for the file hmscalc-0.6.0.tar.gz.

File metadata

  • Download URL: hmscalc-0.6.0.tar.gz
  • Upload date:
  • Size: 7.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.11.15 Linux/6.17.0-1018-azure

File hashes

Hashes for hmscalc-0.6.0.tar.gz
Algorithm Hash digest
SHA256 93f401975ea6f270dc8ae9cd14d0fc99a5b33a6d2f986405b8a8e7b01c9408ce
MD5 adbe3f88372dfebce51dfaff2a3e6cc7
BLAKE2b-256 a536a18c4b03ba6d5e8405a5c0accd0727e6bd946eed4d9c6c40de14e74c8fcb

See more details on using hashes here.

File details

Details for the file hmscalc-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: hmscalc-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 9.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.11.15 Linux/6.17.0-1018-azure

File hashes

Hashes for hmscalc-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 16b17c3e1f39076286a1d11055416ffc84c485acdac2bd0eaa069326d85776e0
MD5 bd22306490ea7bcd71a647740d258d4f
BLAKE2b-256 f3798c6b119dd55d07803a806bccd6a011e184e1a1c0b6e87cf6bacaaf0a11fb

See more details on using hashes here.

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