Skip to main content

hank-format

Shared string formatting functions for standardizing names, dates, and times across the Hank AI stack.

pip install hank-format

Usage

from hank_format import as_name, as_date, as_date_str, as_datetime_str, as_time_str

as_name("Primary: John Doe")                       # 'DOE, JOHN'
as_name("Steven Hardman, APRN - CRNA")             # 'HARDMAN, STEVEN, APRN, CRNA'
as_date("12/31/2020 (age 30 yrs)")                 # datetime.date(2020, 12, 31)
as_date_str("01012024")                            # '2024-01-01'
as_datetime_str("2020-12-31T23:59")                # '2020-12-31 23:59:00'
as_datetime_str("23:59", precision="minute", default_date="2020-12-31")  # '2020-12-31 23:59'
as_time_str("11:30 pm")                            # '23:30'

API

Function Returns Notes
as_name(value) str LAST, FIRST MIDDLE, SUFFIX, upper case. Strips Label: prefixes, [notes], (notes), *, and text after ;.
is_date(value) bool True when a year, month, and day are present.
has_time(value) bool True when an hour and minute are present.
as_date(value) date | None Calendar date only.
as_date_str(value) str YYYY-MM-DD or "".
as_datetime(value, *, default_date=None) datetime | None Midnight when no time is present. Time-only input needs default_date.
as_datetime_str(value, *, precision="second", default_date=None) str YYYY-MM-DD HH:MM:SS, or YYYY-MM-DD HH:MM with precision="minute".
as_time(value) time | None Clock time only.
as_time_str(value, *, precision="minute") str HH:MM, or HH:MM:SS with precision="second".

Conventions:

  • Inputs may be strings, date, datetime, time, or None. Other types raise TypeError.
  • Object variants return None and string variants return "" when no usable value exists.
  • Returned values are timezone-naive and have no microseconds. precision truncates, never rounds.
  • Any parsed date more than two days in the future rolls back 100 years, including four-digit years and year-less MM/DD (12/31/45 is 1945; 12/26 without a time is 1926 when today is 2026-10-08). This is a two-digit-year heuristic inherited from pdf-extractor; strip or validate far-future dates before calling if you need them intact.
  • Year-less MM/DD HH:MM strings take the current year, or the previous year if that would be in the future.

Migrating from pdf-extractor utils

Legacy hank-format
as_name(s) as_name(s) (lists and vStr handling stay in pdf-extractor)
as_date(v, date_only=True, as_dt=True) as_date(v) (returns date)
as_date(v, date_only=True) as_date_str(v)
as_date(v, as_dt=True) as_datetime(v)
as_date(v) as_datetime_str(v)
as_time(v, with_date=False) as_time_str(v)
as_time(v, strict=True) as_datetime_str(v, precision="minute") if has_time(v) else ""
as_time(v, default_date=d) as_datetime_str(v, precision="minute", default_date=d) if has_time(v) else ""
as_time(v) as_datetime_str(v, precision="minute") if is_date(v) and has_time(v) else as_time_str(v)

Legacy as_time returned "" for anything without a time; the new datetime functions format a date-only value as midnight, hence the has_time guards.

Development

Requires uv.

uv sync                      # create .venv with Python 3.12 and the dev group
uv run pytest                # tests with 100% coverage enforced
uv run ruff check . && uv run ruff format --check .
uv run pyright
uv build                     # sdist + wheel into dist/

Releasing

  1. Open a PR against main and add exactly one label: release:patch, release:minor, or release:major.
  2. On merge, the Release workflow bumps __version__ in hank_format/__init__.py, runs the tests, builds, commits Release vX.Y.Z, tags it, and pushes. A separate publish job then uploads the built artifacts to PyPI.
  3. If only the publish job fails (for example, trusted publishing is not configured yet), fix the cause and re-run that failed job. Do not re-run the whole workflow: the version is already bumped and tagged, so a full re-run would bump it again.

One-time setup:

  • On pypi.org, under the hank-format project (or as a pending publisher), add a trusted publisher with owner hank-ai, repository hank-format, workflow release.yml, environment pypi.
  • In the GitHub repo settings, create an environment named pypi.
  • The workflow pushes the version-bump commit to main with the default GITHUB_TOKEN. If main is protected, allow the token to bypass the rule or supply a PAT in a RELEASE_TOKEN secret and use it in the checkout step.

Metadata

Release files for hank-format 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hank-format 0.1.1
File Size Uploaded
hank_format-0.1.1.tar.gz 10.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hank-format 0.1.1
File Interpreter ABI Platform
hank_format-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 20.6 kB

Release files / hank_format-0.1.1.tar.gz

Download URL hank_format-0.1.1.tar.gz
Size 10.5 kB
Tags Source
SHA-256 checksum
How to use checksums
f95b44ebafb64008bcf011622d0d7ce96a2bc3fa61d377a30bf8547142fe0040
BLAKE2b-256 checksum
How to use checksums
4910d3dd2fe2a884827c9c92e299a375a2d25063b5277a8fb00903538577a749
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / hank_format-0.1.1-py3-none-any.whl

Download URL hank_format-0.1.1-py3-none-any.whl
Size 10.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ad0ecff636c573409161e071a2fcf7c2a4e8cdbfe207c65a56cbe73d5a059238
BLAKE2b-256 checksum
How to use checksums
1e4cf397375a65c642c8615c272d1084f1d654e709f17cf9f1d8ca9cb362e4cd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.0

2 release files

0.2.0

2 release files

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page