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:
- ✅ Durations →
monotonic()
- ✅ Benchmarks →
perf_counter()
- ✅ Logging →
ctime()/strftime()
- ✅ CPU time →
process_time()
- ✅ Threads →
thread_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!