Foundation Guide

Python Standard Library: time

šŸ“„ 24 Pages šŸŽÆ Sleep, timestamps, measuring duration

What this page does

Introduces the time module and what you will learn.

Where this fits

This is the starting point. You should know basic Python before starting.

Explanation

The time module handles time-related operations: pausing your program, measuring how long things take, and working with timestamps. By the end of this guide, you will know how to:

  • Pause execution — Make your program wait
  • Get timestamps — Current time as a number
  • Format time — Convert timestamps to readable strings
  • Parse time — Convert strings back to time objects
  • Measure duration — Time how long code takes to run
  • Use different clocks — Wall time vs CPU time vs monotonic
The time module is built into Python. No installation required.

Why this matters

Time operations are everywhere: delays in games, rate limiting APIs, logging timestamps, benchmarking performance, scheduling tasks.

āœ“ Checkpoint

⚠ If something breaks here

Nothing to break yet. Move to Page 2.

What this page does

Sets up a Python file for practicing the time module.

Where this fits

Before writing code, create a workspace.

Code (this page)

mkdir ~/projects/time-practice
cd ~/projects/time-practice
touch time_basics.py

Explanation

These commands:

  • Create a folder called time-practice
  • Enter that folder
  • Create an empty Python file
From now on, you will write code in time_basics.py and run it with python3 time_basics.py.

Why this matters

Having a dedicated file lets you build up code incrementally and re-run to test changes.

āœ“ Checkpoint

⚠ If something breaks here

  • mkdir: File exists: The folder exists. Just cd into it

What this page does

Imports the time module into your Python file.

Where this fits

Your file is ready. Now add the import.

Code (this page)

import time

print("time module imported successfully")

Explanation

Open time_basics.py in VS Code and add this code.

import time loads the module. Like random, we don't use an alias — time is already short and clear.

Run it:

python3 time_basics.py

Output:

time module imported successfully

Why this matters

This import line starts every script that works with time operations.

āœ“ Checkpoint

⚠ If something breaks here

  • ModuleNotFoundError: This shouldn't happen — time is built-in. Check spelling.

What this page does

Pauses program execution for a specified duration.

Where this fits

Module imported. Now use the most common function.

Code (this page)

import time

print("Starting...") time.sleep(2) # Pause for 2 seconds print("2 seconds later!")

time.sleep(0.5) # Pause for half a second print("Half second later!")

Explanation

Run the file and watch:

Starting...
[2 second pause]
2 seconds later!
[0.5 second pause]
Half second later!

time.sleep(seconds):

  • Pauses execution for the specified number of seconds
  • Accepts integers or floats (for sub-second delays)
  • The program does nothing during sleep

Why this matters

Delays are essential for: rate limiting API calls, animations, countdowns, retry logic, polling intervals.

āœ“ Checkpoint

⚠ If something breaks here

  • Program hangs: That's the sleep working. Wait for it to complete.
  • Negative value: sleep(-1) raises ValueError

What this page does

Gets the current time as a Unix timestamp.

Where this fits

You can pause time. Now get the current time.

Code (this page)

import time

now = time.time() print("Current timestamp:", now)

# Timestamps are seconds since January 1, 1970 print("That's seconds since 1970-01-01 00:00:00 UTC")

# Run twice to see it change time.sleep(1) later = time.time() print("One second later:", later) print("Difference:", later - now)

Explanation

Run the file:

Current timestamp: 1737849600.123456
That's seconds since 1970-01-01 00:00:00 UTC
One second later: 1737849601.234567
Difference: 1.111111

time.time() returns a float:

  • Whole part = seconds since "epoch" (Jan 1, 1970)
  • Decimal part = fractional seconds
  • This is called a "Unix timestamp"

Why this matters

Timestamps are the universal way to record when things happen. Logs, databases, and APIs all use them.

āœ“ Checkpoint

⚠ If something breaks here

Nothing should break. Timestamps always work.

What this page does

Converts a timestamp to a human-readable string.

Where this fits

You have a timestamp number. Now make it readable.

Code (this page)

import time

# Current time as readable string now = time.ctime() print("Current time:", now)

# Convert a specific timestamp timestamp = time.time() readable = time.ctime(timestamp) print("From timestamp:", readable)

# Convert a historical timestamp moon_landing = 0 # Epoch = Jan 1, 1970 print("Epoch:", time.ctime(moon_landing))

Explanation

Run the file:

Current time: Sun Jan 26 14:30:45 2026
From timestamp: Sun Jan 26 14:30:45 2026
Epoch: Wed Dec 31 16:00:00 1969

time.ctime(timestamp):

  • Converts timestamp to a readable string
  • If no argument, uses current time
  • Format: Day Mon DD HH:MM:SS YYYY
Note: Epoch shows as Dec 31 1969 because of timezone offset from UTC.

Why this matters

Humans can't read 1737849600. Quick debugging and logging need readable output.

āœ“ Checkpoint

⚠ If something breaks here

  • OSError: Timestamp too large or negative for your system

What this page does

Converts a timestamp to a structured time object.

Where this fits

ctime() gives a string. localtime() gives components.

Code (this page)

import time

# Get structured local time now = time.localtime() print("Full struct:", now)

# Access individual components print(f"Year: {now.tm_year}") print(f"Month: {now.tm_mon}") print(f"Day: {now.tm_mday}") print(f"Hour: {now.tm_hour}") print(f"Minute: {now.tm_min}") print(f"Second: {now.tm_sec}") print(f"Weekday: {now.tm_wday}") # 0=Monday, 6=Sunday print(f"Day of year: {now.tm_yday}")

Explanation

Run the file:

Full struct: time.struct_time(tm_year=2026, tm_mon=1, tm_mday=26, ...)
Year: 2026
Month: 1
Day: 26
Hour: 14
Minute: 30
Second: 45
Weekday: 6
Day of year: 26

time.localtime() returns a struct_time with:

  • tm_year, tm_mon, tm_mday — date components
  • tm_hour, tm_min, tm_sec — time components
  • tm_wday — weekday (0=Monday)
  • tm_yday — day of year (1-366)

Why this matters

When you need specific components (just the hour, just the month), localtime() gives direct access without string parsing.

āœ“ Checkpoint

⚠ If something breaks here

Nothing should break. Try different attributes.

What this page does

Gets structured time in UTC (no timezone offset).

Where this fits

localtime() uses your timezone. gmtime() uses UTC.

Code (this page)

import time

local = time.localtime() utc = time.gmtime()

print("Local time:", time.strftime("%H:%M:%S", local)) print("UTC time: ", time.strftime("%H:%M:%S", utc)) print(f"Difference: {local.tm_hour - utc.tm_hour} hours")

Explanation

Run the file (results depend on your timezone):

Local time: 14:30:45
UTC time:   22:30:45
Difference: -8 hours

time.gmtime():

  • Same structure as localtime()
  • But in UTC (Coordinated Universal Time)
  • No daylight saving adjustments
UTC is the global standard for servers and logs.

Why this matters

When coordinating across timezones (servers, APIs, international users), UTC is the common reference.

āœ“ Checkpoint

⚠ If something breaks here

Nothing should break. Offset depends on your location.

What this page does

Formats time into any string format you want.

Where this fits

ctime() has a fixed format. strftime() is flexible.

Code (this page)

import time

now = time.localtime()

# Different formats print(time.strftime("%Y-%m-%d", now)) # 2026-01-26 print(time.strftime("%d/%m/%Y", now)) # 26/01/2026 print(time.strftime("%B %d, %Y", now)) # January 26, 2026 print(time.strftime("%H:%M:%S", now)) # 14:30:45 print(time.strftime("%I:%M %p", now)) # 02:30 PM print(time.strftime("%A, %B %d", now)) # Sunday, January 26 print(time.strftime("%Y-%m-%d %H:%M:%S", now)) # 2026-01-26 14:30:45

Explanation

Run the file:

2026-01-26
26/01/2026
January 26, 2026
14:30:45
02:30 PM
Sunday, January 26
2026-01-26 14:30:45

Common format codes:

  • %Y = 4-digit year, %y = 2-digit year
  • %m = month (01-12), %B = full month name
  • %d = day (01-31)
  • %H = 24-hour, %I = 12-hour, %p = AM/PM
  • %M = minute, %S = second
  • %A = weekday name

Why this matters

Different systems need different formats: ISO for APIs, local format for users, custom for logs.

āœ“ Checkpoint

⚠ If something breaks here

  • Wrong output: Check format codes (they're case-sensitive)

What this page does

Parses a time string into a struct_time.

Where this fits

strftime() formats time → string. strptime() parses string → time.

Code (this page)

import time

# Parse different formats date_str = "2026-01-26" parsed = time.strptime(date_str, "%Y-%m-%d") print(f"Parsed: {parsed.tm_year}-{parsed.tm_mon}-{parsed.tm_mday}")

# Parse with time datetime_str = "January 26, 2026 14:30" parsed = time.strptime(datetime_str, "%B %d, %Y %H:%M") print(f"Hour: {parsed.tm_hour}, Minute: {parsed.tm_min}")

# Parse timestamp from log log_entry = "26/01/2026 14:30:45" parsed = time.strptime(log_entry, "%d/%m/%Y %H:%M:%S") print(f"Day: {parsed.tm_mday}")

Explanation

Run the file:

Parsed: 2026-1-26
Hour: 14, Minute: 30
Day: 26

time.strptime(string, format):

  • Parses a string using the specified format
  • Returns a struct_time
  • Format must match the string exactly

Why this matters

Incoming data (user input, files, APIs) comes as strings. Parsing converts them to usable time objects.

āœ“ Checkpoint

⚠ If something breaks here

  • ValueError: Format doesn't match the string. Check carefully.

What this page does

Converts a struct_time back to a timestamp.

Where this fits

Complete the round trip: timestamp → struct_time → timestamp.

Code (this page)

import time

# Get current time as struct now_struct = time.localtime() print("Struct:", now_struct)

# Convert to timestamp timestamp = time.mktime(now_struct) print("Timestamp:", timestamp)

# Verify round trip print("Back to ctime:", time.ctime(timestamp))

# Create a specific time new_years = time.strptime("2026-01-01 00:00:00", "%Y-%m-%d %H:%M:%S") new_years_ts = time.mktime(new_years) print(f"New Year 2026 timestamp: {new_years_ts}")

Explanation

Run the file:

Struct: time.struct_time(tm_year=2026, ...)
Timestamp: 1737849045.0
Back to ctime: Sun Jan 26 14:30:45 2026
New Year 2026 timestamp: 1735689600.0

time.mktime(struct_time):

  • Converts struct_time to a Unix timestamp
  • Inverse of localtime()
  • Useful for calculating differences or storing in databases

Why this matters

Sometimes you build a time from components and need a timestamp for storage or comparison.

āœ“ Checkpoint

⚠ If something breaks here

  • OverflowError: Year out of range for timestamps

What this page does

Times how long code takes to execute.

Where this fits

You know timestamps. Now use them for benchmarking.

Code (this page)

import time

# Simple timing start = time.time()

# Simulate work total = 0 for i in range(1000000): total += i

end = time.time() elapsed = end - start

print(f"Sum: {total}") print(f"Time: {elapsed:.4f} seconds")

# Time a sleep (verify it works) start = time.time() time.sleep(0.5) end = time.time() print(f"Sleep took: {end - start:.4f} seconds")

Explanation

Run the file:

Sum: 499999500000
Time: 0.0523 seconds
Sleep took: 0.5012 seconds

Pattern for timing:

  • Record start time
  • Run the code
  • Record end time
  • Calculate difference

Why this matters

Performance matters. Timing tells you which code is slow and whether optimizations help.

āœ“ Checkpoint

⚠ If something breaks here

Nothing should break. Times will vary by machine speed.

What this page does

Provides high-precision timing for benchmarks.

Where this fits

time.time() is good. perf_counter() is better for precise measurements.

Code (this page)

import time

# perf_counter for precise benchmarking start = time.perf_counter()

total = sum(range(1000000))

end = time.perf_counter() elapsed = end - start

print(f"Sum: {total}") print(f"perf_counter time: {elapsed:.6f} seconds") print(f"That's {elapsed * 1000:.3f} milliseconds") print(f"That's {elapsed * 1000000:.0f} microseconds")

Explanation

Run the file:

Sum: 499999500000
perf_counter time: 0.023456 seconds
That's 23.456 milliseconds
That's 23456 microseconds

time.perf_counter():

  • Highest resolution timer available
  • Includes time during sleep
  • NOT related to wall clock time (arbitrary starting point)
  • Best choice for benchmarking

Why this matters

When measuring small code blocks (microseconds), perf_counter() gives more accurate results than time().

āœ“ Checkpoint

⚠ If something breaks here

Nothing should break. Values are always relative.

What this page does

Gets high-precision time in nanoseconds as an integer.

Where this fits

perf_counter() returns float seconds. perf_counter_ns() returns integer nanoseconds.

Code (this page)

import time

# Nanosecond precision (integer) start_ns = time.perf_counter_ns()

total = sum(range(100000))

end_ns = time.perf_counter_ns() elapsed_ns = end_ns - start_ns

print(f"Elapsed: {elapsed_ns} nanoseconds") print(f"That's {elapsed_ns / 1000:.1f} microseconds") print(f"That's {elapsed_ns / 1000000:.3f} milliseconds")

# Compare with regular perf_counter start = time.perf_counter() total = sum(range(100000)) end = time.perf_counter() print(f"\nperf_counter: {(end-start)*1e9:.0f} nanoseconds")

Explanation

Run the file:

Elapsed: 2345678 nanoseconds
That's 2345.7 microseconds
That's 2.346 milliseconds

perf_counter: 2345678 nanoseconds

time.perf_counter_ns():

  • Returns nanoseconds as integer (no float rounding errors)
  • 1 second = 1,000,000,000 nanoseconds
  • Useful for very precise measurements

Why this matters

Floating-point has precision limits. Integer nanoseconds avoid rounding errors in accumulated measurements.

āœ“ Checkpoint

⚠ If something breaks here

Nothing should break. Python 3.7+ required.

What this page does

Provides a clock that never goes backward.

Where this fits

time() can jump (daylight saving, NTP). monotonic() can't.

Code (this page)

import time

# monotonic clock for reliable elapsed time start = time.monotonic()

time.sleep(1.5)

end = time.monotonic() elapsed = end - start

print(f"Elapsed: {elapsed:.3f} seconds")

# Demonstrate it's always increasing print("\nMonotonic values (always increase):") for i in range(5): print(f" {time.monotonic():.6f}") time.sleep(0.1)

Explanation

Run the file:

Elapsed: 1.502 seconds

Monotonic values (always increase): 12345.678901 12345.779012 12345.879123 12345.979234 12346.079345

time.monotonic():

  • Always moves forward (never jumps backward)
  • Unaffected by system clock changes
  • Perfect for timeouts and elapsed time in real applications

Why this matters

If the system clock changes (daylight saving, NTP sync), time() can jump. monotonic() guarantees forward progress.

āœ“ Checkpoint

⚠ If something breaks here

Nothing should break. Monotonic is always safe.

What this page does

Measures CPU time used by your process only.

Where this fits

Wall time includes sleep. Process time is actual computation.

Code (this page)

import time

# Compare wall time vs CPU time print("Heavy computation:") wall_start = time.perf_counter() cpu_start = time.process_time()

total = sum(i*i for i in range(2000000))

wall_end = time.perf_counter() cpu_end = time.process_time()

print(f" Wall time: {wall_end - wall_start:.4f} sec") print(f" CPU time: {cpu_end - cpu_start:.4f} sec")

# Sleep shows the difference print("\nWith sleep:") wall_start = time.perf_counter() cpu_start = time.process_time()

time.sleep(1) # This uses no CPU total = sum(range(100000))

wall_end = time.perf_counter() cpu_end = time.process_time()

print(f" Wall time: {wall_end - wall_start:.4f} sec") print(f" CPU time: {cpu_end - cpu_start:.4f} sec")

Explanation

Run the file:

Heavy computation:
  Wall time: 0.1523 sec
  CPU time:  0.1521 sec

With sleep: Wall time: 1.0034 sec CPU time: 0.0023 sec

Notice:

  • Heavy computation: wall ā‰ˆ CPU (all time is computation)
  • With sleep: wall >> CPU (sleep doesn't use CPU)
time.process_time():
  • Only counts CPU cycles used by your program
  • Excludes sleep, I/O waits, other processes

Why this matters

When profiling, you care about CPU efficiency. Process time isolates computation from waiting.

āœ“ Checkpoint

⚠ If something breaks here

Nothing should break. Compare the two values.

What this page does

Creates a reusable timing utility.

Where this fits

Timing pattern is repetitive. Make it reusable.

Code (this page)

import time

class Timer: def __enter__(self): self.start = time.perf_counter() return self def __exit__(self, *args): self.elapsed = time.perf_counter() - self.start print(f"Elapsed: {self.elapsed:.4f} seconds")

# Use it with Timer(): total = sum(range(1000000)) print(f"Sum: {total}")

with Timer(): time.sleep(0.5) print("Done sleeping")

# Access elapsed time with Timer() as t: data = [i**2 for i in range(100000)]

print(f"Stored elapsed: {t.elapsed:.4f}")

Explanation

Run the file:

Sum: 499999500000
Elapsed: 0.0234 seconds
Done sleeping
Elapsed: 0.5012 seconds
Elapsed: 0.0123 seconds
Stored elapsed: 0.0123

The Timer context manager:

  • Starts timing on with entry
  • Stops and prints on exit
  • Can store elapsed time for later use

Why this matters

Clean, reusable timing. One line to time any block of code.

āœ“ Checkpoint

⚠ If something breaks here

  • IndentationError: Check class and method indentation

What this page does

Builds a practical countdown timer.

Where this fits

Apply time functions to a real use case.

Code (this page)

import time

def countdown(seconds): """Display a countdown timer.""" print(f"Starting {seconds} second countdown...") while seconds > 0: mins, secs = divmod(seconds, 60) timer = f"{mins:02d}:{secs:02d}" print(f"\r{timer}", end="", flush=True) time.sleep(1) seconds -= 1 print("\r00:00") print("Time's up!")

# Run a short countdown countdown(5)

Explanation

Run the file:

Starting 5 second countdown...
00:05
00:04
00:03
00:02
00:01
00:00
Time's up!

Key techniques:

  • divmod(seconds, 60) splits into minutes and seconds
  • \r returns to line start (overwrites previous output)
  • flush=True forces immediate display
  • time.sleep(1) waits between updates

Why this matters

Countdowns are everywhere: Pomodoro timers, cooking timers, exam timers, game timers.

āœ“ Checkpoint

⚠ If something breaks here

  • No overwrite: Some terminals don't support \r. Output will be multiple lines.

What this page does

Limits how often an action can occur.

Where this fits

APIs often require rate limiting. Time makes it possible.

Code (this page)

import time

class RateLimiter: def __init__(self, calls_per_second): self.min_interval = 1.0 / calls_per_second self.last_call = 0 def wait(self): """Wait if needed to respect rate limit.""" now = time.monotonic() elapsed = now - self.last_call if elapsed < self.min_interval: sleep_time = self.min_interval - elapsed time.sleep(sleep_time) self.last_call = time.monotonic()

# Example: max 2 calls per second limiter = RateLimiter(calls_per_second=2)

print("Making 6 API calls at max 2/second:") start = time.perf_counter()

for i in range(6): limiter.wait() print(f" Call {i+1} at {time.perf_counter() - start:.2f}s")

total = time.perf_counter() - start print(f"Total time: {total:.2f}s (expected ~2.5s)")

Explanation

Run the file:

Making 6 API calls at max 2/second:
  Call 1 at 0.00s
  Call 2 at 0.50s
  Call 3 at 1.00s
  Call 4 at 1.50s
  Call 5 at 2.00s
  Call 6 at 2.50s
Total time: 2.50s (expected ~2.5s)

The rate limiter:

  • Calculates minimum interval between calls
  • Sleeps if called too soon
  • Uses monotonic() for reliable timing

Why this matters

APIs ban you for too many requests. Rate limiting keeps you within limits.

āœ“ Checkpoint

⚠ If something breaks here

  • Division by zero: calls_per_second must be > 0

What this page does

Implements exponential backoff for retrying failed operations.

Where this fits

Network calls fail. Backoff retries intelligently.

Code (this page)

import time
import random

def retry_with_backoff(func, max_retries=5, base_delay=1.0): """Retry a function with exponential backoff.""" for attempt in range(max_retries): try: return func() except Exception as e: if attempt == max_retries - 1: raise # Last attempt, give up # Exponential backoff with jitter delay = base_delay * (2 ** attempt) jitter = random.uniform(0, delay * 0.1) total_delay = delay + jitter print(f"Attempt {attempt + 1} failed: {e}") print(f"Retrying in {total_delay:.2f} seconds...") time.sleep(total_delay)

# Simulate flaky operation (fails 70% of the time) attempt_count = 0

def flaky_operation(): global attempt_count attempt_count += 1 if random.random() < 0.7: raise ConnectionError(f"Network error on attempt {attempt_count}") return "Success!"

# Test it random.seed(42) try: result = retry_with_backoff(flaky_operation) print(f"Result: {result}") except Exception as e: print(f"All retries failed: {e}")

Explanation

Run the file:

Attempt 1 failed: Network error on attempt 1
Retrying in 1.05 seconds...
Attempt 2 failed: Network error on attempt 2
Retrying in 2.18 seconds...
Attempt 3 failed: Network error on attempt 3
Retrying in 4.31 seconds...
Result: Success!

Exponential backoff:

  • Delay doubles each retry (1s, 2s, 4s, 8s...)
  • Jitter adds randomness to prevent thundering herd
  • Eventually gives up after max retries

Why this matters

Network reliability. Every production system needs retry logic with backoff.

āœ“ Checkpoint

⚠ If something breaks here

  • Runs forever: Make sure max_retries is reasonable

What this page does

Limits how long an operation can run.

Where this fits

Sometimes code hangs. Timeouts prevent infinite waits.

Code (this page)

import time

def with_timeout(func, timeout_seconds, check_interval=0.1): """ Simple timeout pattern (polling-based). Note: This is a simplified example. For real timeouts, use threading or asyncio. """ start = time.monotonic() deadline = start + timeout_seconds while time.monotonic() < deadline: # Try the operation result = func() if result is not None: return result time.sleep(check_interval) raise TimeoutError(f"Operation timed out after {timeout_seconds}s")

# Simulate long-running task counter = 0

def slow_task(): """Returns result after 5 calls, None otherwise.""" global counter counter += 1 print(f" Attempt {counter}...") if counter >= 5: return "Task complete!" return None

# Test with sufficient timeout print("Test 1: 2 second timeout (should succeed)") counter = 0 try: result = with_timeout(slow_task, timeout_seconds=2) print(f"Result: {result}") except TimeoutError as e: print(f"Failed: {e}")

# Test with insufficient timeout print("\nTest 2: 0.3 second timeout (should fail)") counter = 0 try: result = with_timeout(slow_task, timeout_seconds=0.3) print(f"Result: {result}") except TimeoutError as e: print(f"Failed: {e}")

Explanation

Run the file:

Test 1: 2 second timeout (should succeed)
  Attempt 1...
  Attempt 2...
  Attempt 3...
  Attempt 4...
  Attempt 5...
Result: Task complete!

Test 2: 0.3 second timeout (should fail) Attempt 1... Attempt 2... Attempt 3... Failed: Operation timed out after 0.3s

Pattern:

  • Set a deadline using monotonic()
  • Check deadline in each iteration
  • Raise TimeoutError if exceeded

Why this matters

Hanging operations freeze your program. Timeouts keep things responsive.

āœ“ Checkpoint

⚠ If something breaks here

Nothing should break. This is a simplified pattern.

What this page does

Summarizes when to use each clock type.

Where this fits

You've learned multiple clocks. Know which to use.

Explanation

ClockUse CaseNotes
time()Timestamps, loggingCan jump with clock changes
perf_counter()BenchmarkingHighest precision
perf_counter_ns()Nanosecond benchmarksInteger, no float errors
monotonic()Timeouts, intervalsNever goes backward
process_time()CPU profilingExcludes sleep/IO

Decision guide:

  • Need a timestamp for storage/display? → time()
  • Measuring code performance? → perf_counter()
  • Need reliable elapsed time in production? → monotonic()
  • Measuring CPU usage specifically? → process_time()

Why this matters

Using the wrong clock causes bugs: timeouts that fail during daylight saving, benchmarks with wrong precision.

āœ“ Checkpoint

⚠ If something breaks here

Nothing to break. This is reference material.

What this page does

Quick reference for all time functions covered.

Where this fits

Lookup table after completing the guide.

Explanation

### Core Functions

FunctionReturnsDescription
sleep(secs)NonePause execution
time()floatUnix timestamp
ctime(ts)strReadable time string
localtime(ts)struct_timeLocal time components
gmtime(ts)struct_timeUTC time components
mktime(st)floatstruct_time → timestamp
strftime(fmt, st)strFormat time to string
strptime(s, fmt)struct_timeParse string to time

### Clocks

FunctionReturnsBest For
perf_counter()floatBenchmarking
perf_counter_ns()intPrecise benchmarks
monotonic()floatTimeouts/intervals
process_time()floatCPU profiling

### Common Format Codes

CodeMeaningExample
%Y4-digit year2026
%mMonth (01-12)01
%dDay (01-31)26
%HHour 24h (00-23)14
%IHour 12h (01-12)02
%MMinute (00-59)30
%SSecond (00-59)45
%pAM/PMPM
%AWeekday nameSunday
%BMonth nameJanuary

Why this matters

āœ“ Checkpoint

⚠ If something breaks here

Nothing to break. Reference only.

What this page does

Confirms you have mastered all skills in this guide.

Where this fits

This is the end. Verify everything works together.

Explanation

Complete this final test in your time_basics.py:

import time

print("=== Time Module Final Test ===\n")

# 1. Current timestamp and readable time ts = time.time() print(f"1. Timestamp: {ts:.0f}") print(f" Readable: {time.ctime(ts)}")

# 2. Format current time now = time.localtime() formatted = time.strftime("%Y-%m-%d %H:%M:%S", now) print(f"\n2. Formatted: {formatted}")

# 3. Parse a date string date_str = "2026-12-25" parsed = time.strptime(date_str, "%Y-%m-%d") print(f"\n3. Parsed '{date_str}': month={parsed.tm_mon}, day={parsed.tm_mday}")

# 4. Benchmark with perf_counter start = time.perf_counter() total = sum(i*i for i in range(500000)) elapsed = time.perf_counter() - start print(f"\n4. Computation took {elapsed*1000:.2f} ms")

# 5. Compare wall time vs CPU time print("\n5. Wall vs CPU time (with sleep):") wall_start = time.perf_counter() cpu_start = time.process_time()

time.sleep(0.5) _ = sum(range(100000))

wall_elapsed = time.perf_counter() - wall_start cpu_elapsed = time.process_time() - cpu_start

print(f" Wall: {wall_elapsed:.3f}s") print(f" CPU: {cpu_elapsed:.3f}s")

# 6. Short countdown print("\n6. Countdown:") for i in range(3, 0, -1): print(f" {i}...") time.sleep(1) print(" Done!")

print("\nāœ“ Time Module Fundamentals Complete!")

Run it. If you understand every line, you've completed the guide.

Why this matters

You now control time in Python: pausing, measuring, formatting, and benchmarking.

āœ“ Checkpoint

Contents