Skip to main content

ga-tictoc

ga-tictoc helps you measure elapsed time in Python programs, estimate how long a loop or job still needs, inspect processing speed, and log progress messages with readable timing information.

The distribution is named ga-tictoc; the Python import remains tictoc.

The main class is TicToc. It starts counting as soon as you create it.

from tictoc import TicToc

timer = TicToc()

# Code you want to measure

print(timer.toc())

Example output:

00:01:12

For a complete guide to all classes, methods, placeholders, parsing formats, casts, comparisons, and arithmetic operations, see docs/usage.md.

Release maintainers can find the PyPI publishing setup in docs/publishing.md.

Installation

Install or upgrade to the latest stable release from PyPI:

python -m pip install --upgrade ga-tictoc

Install from a GitHub release:

python -m pip install "https://github.com/andreagemma/tictoc/releases/download/v0.2.1/ga_tictoc-0.2.1-py3-none-any.whl"

Install from a local source checkout:

python -m pip install -e .

For more flexible date string parsing, install the optional parser support:

python -m pip install "ga-tictoc[dateutil]"

Quick Start

Measure Elapsed Time

from tictoc import TicToc

tt = TicToc()

# Work...

elapsed = tt.toc()
print(elapsed)  # Human-readable value
print(elapsed.seconds)  # Total seconds

toc() is an alias for elapsed_time().

tt.elapsed_time()
tt.elapsed_origin_time()

elapsed_time() measures from the most recent tic().
elapsed_origin_time() measures from the moment the timer was created.

Reset the Timer

tic() resets the start time and returns the same object, so it works well with method chaining.

tt = TicToc()

tt.tic().info("starting again")

Named Timers

One TicToc object can manage multiple independent named timers.

tt = TicToc()

tt.tic("download")
# Download...

tt.tic("parse")
# Parse...

print(tt.toc("download"))
print(tt.toc("parse"))

You can also access a named timer directly:

download_timer = tt["download"]
print(download_timer.elapsed_time())

Progress, ETA, and Speed

When you know the total number of steps, TicToc can estimate remaining time, total time, end time, and processing speed.

from tictoc import TicToc

tt = TicToc(total=100)

for i in range(1, 101):
    # Process one step
    if i % 10 == 0:
        print(
            i,
            tt.elapsed_time(),
            tt.remaining_time(i=i),
            tt.total_time(i=i),
            tt.end_time(i=i),
            tt.speed(i=i),
        )

Useful methods:

  • remaining_time(i=..., total=...): estimate time left.
  • total_time(i=..., total=...): estimate total execution time.
  • end_time(i=..., total=...): estimate when the job will finish.
  • speed(i=...): return a TicTocSpeed object.
  • percent(i=..., total=...): return completion percentage.

Estimation Methods

Choose how remaining time should be estimated with method.

tt.remaining_time(i=i, total=100, method="origin")
tt.remaining_time(i=i, total=100, method="last")
tt.remaining_time(i=i, total=100, method="moving", n=5)
tt.remaining_time(i=i, total=100, method="ema", n=5)
  • origin: average speed since the latest tic().
  • last: speed from the latest interval between two updates.
  • moving: average speed over the latest n updates.
  • ema: exponential moving average over the latest updates.

Built-In Logging

TicToc can also log progress. If you do not pass a logger, it uses an internal logger named tictoc.

import logging
from tictoc import TicToc

logging.basicConfig(level=logging.INFO)

tt = TicToc(total=50)

for i in range(1, 51):
    # Work...
    tt.info("{i}/{tot} elapsed={et} eta={rt} speed={v}", i=i, each=10)

each=10 logs only every 10 steps.

Available logging methods:

tt.debug("...")
tt.info("...")
tt.warning("...")
tt.error("...")
tt.exception("...")

You can also pass your own logger:

import logging
from tictoc import TicToc

logger = logging.getLogger("my-job")
tt = TicToc(logger=logger)

Log Placeholders

Progress messages support quick placeholders.

Placeholder Meaning
{i} or {counter} current step
{tot} or {total} total steps
{percent_str} formatted percentage
{et} elapsed time
{eot} elapsed origin time
{rt} remaining time
{tt} estimated total time
{v} speed
{start} start time
{origin} object creation time
{end} estimated end time

Use suffixes when you want numeric values:

tt.info("elapsed={et_s:.2f}s eta={rt_m:.1f}min speed={v_h:.0f}/h", i=i)

Common suffixes:

  • _s, _sec, _seconds
  • _m, _min, _minutes
  • _h, _hours
  • _d, _days
  • _str

Intervals: TicTocInterval

TicTocInterval represents a duration.

from datetime import timedelta
from tictoc import TicTocInterval

a = TicTocInterval("1 day 2 hours")
b = TicTocInterval(timedelta(minutes=30))
c = TicTocInterval(10)  # Seconds

print(a + b)
print(c * 3)
print(float(a))  # Total seconds
print(a.total_hours)
print(a.component_days)

Accepted formats include:

TicTocInterval("1 day 2 seconds")
TicTocInterval("1d 2h 3m 4s")
TicTocInterval("01:02:03")
TicTocInterval("1.02:00:53")
TicTocInterval("PT1H30M")

Timestamps: TicTocTime

TicTocTime represents a point in time.

from datetime import datetime, timedelta
from tictoc import TicTocTime

now = TicTocTime.now()
start = TicTocTime.from_string("2026-06-16 12:00:00")
later = start + timedelta(minutes=10)

print(now)
print(later - start)  # TicTocInterval
print(start.year, start.month, start.day)
print(float(start))  # Unix timestamp

You can create a TicTocTime from:

TicTocTime.now()
TicTocTime.from_timestamp(1_781_600_000)
TicTocTime.from_datetime(datetime.now())
TicTocTime.from_string("2026-06-16 12:00:00")

Speed: TicTocSpeed

TicTocSpeed represents steps per second and gives you ready-to-use conversions.

from tictoc import TicTocSpeed, TicTocInterval

speed = TicTocSpeed.from_steps(120, TicTocInterval.from_minutes(2))

print(speed)  # 1 step/s
print(speed.steps_per_second)
print(speed.steps_per_minute)
print(speed.steps_per_hour)

Complete Example

import logging
import time

from tictoc import TicToc

logging.basicConfig(level=logging.INFO, format="%(message)s")

tt = TicToc(total=20)

for i in range(1, 21):
    time.sleep(0.1)
    tt.info(
        "{i}/{tot} ({percent_str}) elapsed={et} eta={rt} end={end} speed={v}",
        i=i,
        each=5,
    )

print("finished in", tt.elapsed_time())

Example output:

5/20 (25.0%) elapsed=0.501 s eta=1.5 s end=2026-06-16 12:00:03 speed=10 steps/s
10/20 (50.0%) elapsed=1 s eta=1 s end=2026-06-16 12:00:03 speed=10 steps/s
15/20 (75.0%) elapsed=1.5 s eta=0.5 s end=2026-06-16 12:00:03 speed=10 steps/s
20/20 (100.0%) elapsed=2 s eta=0 s end=2026-06-16 12:00:03 speed=10 steps/s
finished in 2 s

License

Distributed under the MIT License. See LICENSE.

Third-party dependency notices and archived license files are available in:

Release files for ga-tictoc 0.2.4

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

Source distribution (sdist)

Source distribution for ga-tictoc 0.2.4
File Size Uploaded
ga_tictoc-0.2.4.tar.gz 32.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ga-tictoc 0.2.4
File Interpreter ABI Platform
ga_tictoc-0.2.4-py3-none-any.whl Python 3 none any Details

Total release size: 52.7 kB

Release files / ga_tictoc-0.2.4.tar.gz

Download URL ga_tictoc-0.2.4.tar.gz
Size 32.7 kB
Tags Source
SHA-256 checksum
How to use checksums
8f1fe4f6b6938cd7faa7623e19fdc8d76bccd53b6e4686cbddf04614bf4f03cc
BLAKE2b-256 checksum
How to use checksums
ecbbbf349cff3bb02d26983be06e7fc81e623b2637cf7922439ea1110fca5c39
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 Sep 8, 2026.

Transparency log

Release files / ga_tictoc-0.2.4-py3-none-any.whl

Download URL ga_tictoc-0.2.4-py3-none-any.whl
Size 20.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
05208e3d8633a71c52ff8151c1cd6988031439c7e9daff137b4d093c59d18919
BLAKE2b-256 checksum
How to use checksums
4be31030b785e62aef29a2b0345d6fbb6fc269a9faef14ddbfe314bfecc1eebf
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 Sep 8, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.5

2 release files

This release

0.2.4 This release

2 release files

0.2.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