How I Learned to Use Python's Time Module

Table of Contents

Remember how I shared how Enums saved me from string typos? Well, I recently had another “aha!” moment with Python’s time module. What seemed like a boring collection of time functions actually solved real headaches in my automation scripts!

Let me show you how understanding these tools made my scripts more precise and reliable - just like Enums did for my code quality.

The Problem: My Script’s Timing Was All Wrong

I used to rely solely on time.time() for everything - measuring durations, logging timestamps, you name it. Then one day, my scheduled tasks started acting weird:

# My old approach
start = time.time()
do_some_work()
duration = time.time() - start
print(f"Took {duration:.2f} seconds")  # Sometimes showed negative numbers?!

Turns out, when the system clock adjusted (like midnight clock sync, or daylight saving time ghosts), my simple timing broke completely! That’s when I discovered there’s a better way…

time.monotonic(): My New Best Friend

For measuring durations, time.monotonic() became my go-to:

start = time.monotonic()
do_some_work()
duration = time.monotonic() - start
print(f"Took {duration:.2f} real seconds")  # Now always correct!

Why I love it:

  • Never goes backward (even if system clock changes)
  • Perfect for measuring timeouts and durations
  • The name says exactly what it does!

When You Need Even More Precision: time.perf_counter()

When I started optimizing my data processing script, I needed nanosecond precision:

start = time.perf_counter()
process_large_dataset()
end = time.perf_counter()
print(f"Processing took {end - start:.6f} seconds")  # Shows microseconds!

Pro tip: I use this for benchmarking different approaches to see which is truly fastest.

Making Timestamps Human-Friendly

Remember how Enums made my code more readable? These time functions did the same for my logs:

Before (messy):

print(f"Error at {time.time()}")  # "Error at 1745678923.42" 🤔

After (clear):

print(f"Error at {time.ctime()}")  # "Error at Tue Jul 15 14:30:00 2025"

Or for custom formats:

print(time.strftime("%Y-%m-%d %H:%M:%S"))  # "2025-07-15 14:30:00"

Real-World Timezone Headache Solved

When my script needed to work across timezones, I was saved by:

# Convert local to UTC
local_time = time.localtime()
utc_time = time.gmtime(time.mktime(local_time))
print(f"UTC: {time.strftime('%H:%M', utc_time)}")

Bonus: Discovered these helpful guys:

print(f"Our timezone is {time.tzname[0]} (UTC{time.timezone/3600:+g})")
# Prints "Our timezone is WIB (UTC-7)"

Thread Timing Made Simple

When I added multithreading (scary!), time.thread_time() helped me debug:

start = time.thread_time()
# ...thread work...
print(f"Used {time.thread_time() - start} CPU seconds")

Unlike regular timing, this only counts when my thread was actually running!

My New Timing Checklist

Now I use the right tool for each job:

  • Durationsmonotonic()
  • Benchmarksperf_counter()
  • Loggingctime()/strftime()
  • CPU timeprocess_time()
  • Threadsthread_time()

Final Thoughts

Just like how Enums made my code safer from typos, understanding these time functions made my scripts more reliable against real-world timing quirks. The best part? They’re all built into Python - no extra libraries needed!

Next time you reach for time.time(), ask yourself: “Is this really the best tool for what I need?” Your future self (and your script’s users) will thank you!