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.
ā 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.
ā 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 timeprint("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.
ā 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 timeprint("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.
ā 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 timenow = 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.
ā 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.
ā 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.
ā 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 timelocal = 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.
ā 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 timenow = 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.
ā 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.
ā 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.
ā 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.
ā 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().
ā 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 millisecondsperf_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.
ā 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 secondsMonotonic 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.
ā 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 secWith 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.
ā 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 timeclass 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.
ā 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 timedef 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.
ā 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 timeclass 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.
ā 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 randomdef 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.
ā 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 timedef 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.
ā 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
| Clock | Use Case | Notes |
time() | Timestamps, logging | Can jump with clock changes |
perf_counter() | Benchmarking | Highest precision |
perf_counter_ns() | Nanosecond benchmarks | Integer, no float errors |
monotonic() | Timeouts, intervals | Never goes backward |
process_time() | CPU profiling | Excludes 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.
ā 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
| Function | Returns | Description |
sleep(secs) | None | Pause execution |
time() | float | Unix timestamp |
ctime(ts) | str | Readable time string |
localtime(ts) | struct_time | Local time components |
gmtime(ts) | struct_time | UTC time components |
mktime(st) | float | struct_time ā timestamp |
strftime(fmt, st) | str | Format time to string |
strptime(s, fmt) | struct_time | Parse string to time |
### Clocks
| Function | Returns | Best For |
perf_counter() | float | Benchmarking |
perf_counter_ns() | int | Precise benchmarks |
monotonic() | float | Timeouts/intervals |
process_time() | float | CPU profiling |
### Common Format Codes
| Code | Meaning | Example |
%Y | 4-digit year | 2026 |
%m | Month (01-12) | 01 |
%d | Day (01-31) | 26 |
%H | Hour 24h (00-23) | 14 |
%I | Hour 12h (01-12) | 02 |
%M | Minute (00-59) | 30 |
%S | Second (00-59) | 45 |
%p | AM/PM | PM |
%A | Weekday name | Sunday |
%B | Month name | January |
Why this matters
ā 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 timeprint("=== 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.