Ei vielä käännetty
Tätä sivua ei ole vielä käännetty suomeksi, joten se näytetään englanniksi. Auta kääntämään
time Module Complexity¶
The time module reads the system's clocks, sleeps, and converts between timestamps,
struct_time tuples and strings. It is a thin layer over the C library: a clock read is one
call into the operating system, and a conversion fills or reads one fixed-size record.
f is the characters in a format string and n is the characters in the string strptime()
parses. Every other operation takes a fixed-size input - a clock id, a timestamp, or a
struct_time - and is O(1), with one exception: on Linux, reading the process's CPU time sums
the CPU time of all t threads in the process. The C library's own work is priced O(1)
otherwise: reading any other clock, and consulting the timezone rules that localtime(),
mktime() and tzset() rely on.
Complexity Reference¶
Clocks¶
| Operation | Time | Space | Notes |
|---|---|---|---|
time.time(), time.time_ns() |
O(1) | O(1) | Seconds since the epoch; the system clock can be set back, so two readings can go backwards. The _ns form returns an int and keeps the nanoseconds a float rounds away |
time.monotonic(), time.monotonic_ns() |
O(1) | O(1) | Never goes backwards; the clock for timeouts and durations |
time.perf_counter(), time.perf_counter_ns() |
O(1) | O(1) | The highest-resolution clock for short durations; counts time spent in sleep() |
time.process_time(), time.process_time_ns() |
O(t) | O(1) | CPU time of the whole process; time spent in sleep() does not count. Linux sums the CPU time of all t threads, unless a process-wide CPU timer such as setitimer(ITIMER_PROF, ...) is armed |
time.thread_time(), time.thread_time_ns() |
O(1) | O(1) | CPU time of the calling thread only; availability is platform-dependent |
time.get_clock_info(name) |
O(1); O(t) for 'process_time' on Linux |
O(1) | A namespace of implementation, monotonic, adjustable and resolution |
POSIX clocks¶
| Operation | Time | Space | Notes |
|---|---|---|---|
time.clock_gettime(clk_id), time.clock_gettime_ns(clk_id) |
O(1); O(t) for CLOCK_PROCESS_CPUTIME_ID on Linux |
O(1) | Unix only; reads the clock a CLOCK_* id names |
time.clock_settime(clk_id, t), time.clock_settime_ns(clk_id, t) |
O(1) | O(1) | Unix only, and needs privileges |
time.clock_getres(clk_id) |
O(1) | O(1) | Unix only; the clock's resolution, not the cost of reading it |
time.pthread_getcpuclockid(thread_id) |
O(1) | O(1) | Unix only; the id of a thread's CPU-time clock, for clock_gettime() |
time.CLOCK_REALTIME, time.CLOCK_MONOTONIC, time.CLOCK_MONOTONIC_RAW, time.CLOCK_BOOTTIME, time.CLOCK_PROCESS_CPUTIME_ID, time.CLOCK_THREAD_CPUTIME_ID, time.CLOCK_TAI, time.CLOCK_HIGHRES, time.CLOCK_PROF, time.CLOCK_UPTIME, time.CLOCK_UPTIME_RAW |
O(1) | O(1) | Integer clock ids; which of them exist is platform-dependent |
time.CLOCK_MONOTONIC_RAW_APPROX, time.CLOCK_UPTIME_RAW_APPROX |
O(1) | O(1) | Python 3.13+; platform-dependent integer clock ids |
Sleeping¶
| Operation | Time | Space | Notes |
|---|---|---|---|
time.sleep(secs) |
O(1) | O(1) | Blocks the calling thread for at least secs; the wait costs no CPU time, whatever secs is |
Conversions¶
| Operation | Time | Space | Notes |
|---|---|---|---|
time.gmtime([secs]), time.localtime([secs]) |
O(1) | O(1) | A timestamp to a struct_time, in UTC or local time; the current time when secs is omitted |
time.mktime(t) |
O(1) | O(1) | A local struct_time back to a timestamp |
time.asctime([t]), time.ctime([secs]) |
O(1) | O(1) | 24 characters for any four-digit year |
time.strftime(format[, t]) |
O(f) | O(f) | Output grows with the format: each directive expands to a bounded number of characters |
time.strptime(string[, format]) |
O(n) | O(n) | Each format is compiled once and cached; the cache is small and is cleared wholesale when full |
struct_time¶
| Operation | Time | Space | Notes |
|---|---|---|---|
time.struct_time(sequence) |
O(1) | O(1) | Nine to eleven items; the tenth and eleventh fill tm_zone and tm_gmtoff |
struct_time.tm_year, struct_time.tm_mon, struct_time.tm_mday, struct_time.tm_hour, struct_time.tm_min, struct_time.tm_sec, struct_time.tm_wday, struct_time.tm_yday, struct_time.tm_isdst |
O(1) | O(1) | The nine fields that indexing and unpacking reach |
struct_time.tm_zone, struct_time.tm_gmtoff |
O(1) | O(1) | Attributes only: not part of the nine-item tuple |
Timezone attributes¶
| Operation | Time | Space | Notes |
|---|---|---|---|
time.timezone, time.altzone, time.daylight, time.tzname |
O(1) | O(1) | Module attributes, set at import and again by tzset() |
time.tzset() |
O(1) | O(1) | Unix only; re-reads TZ and refreshes the four attributes above |
Reading Clocks¶
Choosing a Clock¶
time() follows the system clock, which can be set back, so a duration measured with it can
come out negative. Measure durations with monotonic() or perf_counter(), and use the _ns
forms where the nanoseconds matter: a float timestamp near the present cannot hold them.
import math
import time
now = time.time() # O(1)
now_ns = time.time_ns() # O(1)
assert isinstance(now_ns, int)
assert math.ulp(now) > 1e-9 # a float this large cannot resolve one nanosecond
start = time.monotonic() # O(1)
elapsed = time.monotonic() - start
assert elapsed >= 0
info = time.get_clock_info("monotonic") # O(1)
assert info.monotonic is True
assert info.resolution > 0
CPU Time¶
process_time() and thread_time() count CPU time, so a thread that is blocked adds nothing
to them. perf_counter() counts wall-clock time, sleep included.
import time
cpu_before = time.process_time() # O(t) on Linux - sums every thread
wall_before = time.perf_counter() # O(1)
time.sleep(0.05) # O(1) - the thread waits, it does not work
cpu_spent = time.process_time() - cpu_before
wall_spent = time.perf_counter() - wall_before
assert wall_spent >= 0.05
assert cpu_spent < wall_spent
POSIX Clocks¶
On Unix, clock_gettime() reads a clock by id. Which ids exist depends on the platform, so
check before reaching for one.
import time
if hasattr(time, "clock_gettime") and hasattr(time, "CLOCK_MONOTONIC"):
seconds = time.clock_gettime(time.CLOCK_MONOTONIC) # O(1)
nanoseconds = time.clock_gettime_ns(time.CLOCK_MONOTONIC) # O(1)
assert isinstance(seconds, float) and isinstance(nanoseconds, int)
assert 0 < time.clock_getres(time.CLOCK_MONOTONIC) <= 1 # O(1)
Converting Timestamps¶
A struct_time has a fixed shape whatever the timestamp, so converting either way is O(1).
Its nine fields are reachable by index and by name; tm_zone and tm_gmtoff only by name.
import time
utc = time.gmtime(0) # O(1)
assert (utc.tm_year, utc.tm_mon, utc.tm_mday) == (1970, 1, 1)
assert utc[0] == utc.tm_year # O(1) either way
assert len(utc) == 9
assert utc.tm_gmtoff == 0 and utc.tm_zone not in utc # O(1) - by name only
local = time.localtime(1_000_000_000) # O(1)
assert time.mktime(local) == 1_000_000_000 # O(1)
rebuilt = time.struct_time(tuple(utc)) # O(1)
assert rebuilt == utc
Formatting and Parsing¶
These are the only operations on this page whose cost follows an input: strftime() the format
it is given, and strptime() the string it parses. asctime() and ctime() have a fixed
layout instead.
import time
moment = time.gmtime(0)
stamp = time.strftime("%Y-%m-%d %H:%M:%S", moment) # O(f)
assert stamp == "1970-01-01 00:00:00"
parsed = time.strptime("2026-01-30 12:34:56", "%Y-%m-%d %H:%M:%S") # O(n)
assert (parsed.tm_year, parsed.tm_hour) == (2026, 12)
assert time.asctime(moment) == "Thu Jan 1 00:00:00 1970" # O(1)
The strptime Format Cache¶
strptime() compiles its format to a regular expression and caches it, so a format reused in a
loop is compiled once and each later call is only the O(n) match. The cache holds a few formats
and is emptied all at once when it is full, so a program rotating through more formats than
that compiles on almost every call. datetime.strptime() shares the same cache.
import time
lines = ["2026-01-30 08:00", "2026-01-30 09:15", "2026-01-31 17:45"]
fmt = "%Y-%m-%d %H:%M"
hours = [time.strptime(line, fmt).tm_hour for line in lines] # compiled once, then O(n) each
assert hours == [8, 9, 17]
try:
time.strptime("2026-01-30", fmt)
except ValueError as error:
assert "does not match format" in str(error)
else:
raise AssertionError("a string missing its time parsed")
Timezone Attributes¶
import time
offset = time.timezone # O(1) - seconds west of UTC, outside DST
dst_offset = time.altzone # O(1) - the same with DST in effect
has_dst = time.daylight # O(1)
standard, summer = time.tzname # O(1) - a two-string tuple
assert isinstance(offset, int) and isinstance(dst_offset, int)
if hasattr(time, "tzset"):
time.tzset() # O(1) - re-reads TZ and refreshes the four above
assert len(time.tzname) == 2
Common Patterns¶
Timing a Block of Code¶
import time
start = time.perf_counter_ns() # O(1)
total = sum(range(100_000))
elapsed_ns = time.perf_counter_ns() - start # O(1)
assert total == 4_999_950_000
assert elapsed_ns >= 0
Waiting With a Deadline¶
import time
deadline = time.monotonic() + 0.05 # O(1) - unaffected if the system clock is set
while time.monotonic() < deadline:
time.sleep(0.01) # O(1) CPU per wait
assert time.monotonic() >= deadline
Performance Best Practices¶
✅ Do:
- Measure durations and deadlines with
monotonic()orperf_counter(), which never go backwards - Use
process_time()orthread_time()to separate CPU work from time spent waiting - Reuse one
strptime()format across a loop, so it is compiled once - Use the
_nsclock forms when nanoseconds matter
❌ Avoid:
- Timing with
time()- a clock adjustment can make the result wrong or negative - Rotating through many
strptime()formats - past the cache's size, most calls recompile - A busy loop polling a clock where
sleep()would wait without spending CPU
Version Notes¶
- Python 3.13+:
strptime()issues aDeprecationWarningfor a format with a day of the month but no year - Python 3.15+:
strptime()raisesValueErrorfor a format with a day of the month but no year, instead of warning - All Python 3:
time()follows the system clock and can go backwards when it is set