datetime.time

A wall-clock reading without a date. You can compare and format it, but not add a timedelta to it — without a date, "23:30 + 45 minutes" has nowhere to roll over to.

datetime classPython 2.3+Live demo
Common call
time(9, 30)
Returns
datetime.time(9, 30)
Replaces
(hour, minute) tuples and "HH:MM" strings
Watch out
time + timedelta raises TypeError — combine with a date first
time(hourhour — 0 to 23.type: int · default: 0=0, minuteminute — 0 to 59.type: int · default: 0=0, secondsecond — 0 to 59.type: int · default: 0=0, microsecondmicrosecond — 0 to 999999.type: int · default: 0=0, tzinfotzinfo — Usually None. With a fixed-offset timezone the time is aware.type: tzinfo | None · default: None=None, *, foldfold — Keyword-only, 0 or 1; see the fold attribute.type: int · default: 0=0)
→ time

Demo

Live evaluation
Every argument is optional; each is range-checked.
Try:
Inputs
hourinthour
minuteintminute
secondintsecond
Code
from datetime import time
t = time(14, 30, 0)
(t, str(t), t.strftime('%I:%M'))
Result
(datetime.time(14, 30), '14:30:00', '02:30')

Hour 24 is rejected by the constructor (24:00 is not a time of day here), and a minute of 60 does not carry into the hour. In the "add minutes" tab the date is a throwaway anchor: 23:30 + 45 minutes is 00:15 with one day crossed.

Parameters

NameTypeRequiredDescription
hourintno (0)0 to 23.
minuteintno (0)0 to 59.
secondintno (0)0 to 59.
microsecondintno (0)0 to 999999.
tzinfotzinfo | Noneno (None)Usually None. With a fixed-offset timezone the time is aware.
foldintno (0)Keyword-only, 0 or 1; see the fold attribute.

Return value

time — An immutable time-of-day value, naive or (with tzinfo) aware.

Common patterns

Is a time inside opening hours?
Chained comparisons work on naive times.
from datetime import time
def is_open(t, opens=time(9), closes=time(17, 30)):
    return opens <= t < closes
Minutes between two times
Anchor both to the same date, subtract, convert.
from datetime import date, datetime
d = date(2000, 1, 1)
minutes = (datetime.combine(d, end) - datetime.combine(d, start)).total_seconds() / 60
Time part of a datetime
.time() drops tzinfo; .timetz() keeps it.
wall_clock = dt.time()

Examples

1. Construct
from datetime import time time(14, 30)
Returns
datetime.time(14, 30)
2. All defaults: midnight
from datetime import time time()
Returns
datetime.time(0, 0)
3. Midnight is truthy (3.5+)
from datetime import time bool(time(0))
Returns
True
4. Compare
from datetime import time time(9) < time(17, 30)
Returns
True
5. Format
from datetime import time time(9, 5).strftime('%H:%M')
Returns
'09:05'
6. No subtraction either
from datetime import time time(17) - time(9)
Returns
TypeError: unsupported operand type(s) for -: 'datetime.time' and 'datetime.time'
7. Aware times compare in UTC
from datetime import time, timedelta, timezone, UTC time(12, tzinfo=timezone(timedelta(hours=2))) == time(10, tzinfo=UTC)
Returns
True

Pitfalls

1. Adding a timedelta to a time
time has no date to roll over into, so + is not defined. Combine with a date, add, take .time().
time + timedelta
from datetime import time, timedelta
time(23, 30) + timedelta(minutes=45)
TypeError: unsupported operand type(s) for +: 'datetime.time' and 'datetime.timedelta'
via datetime
from datetime import date, datetime, time, timedelta
(datetime.combine(date(2000, 1, 1), time(23, 30)) + timedelta(minutes=45)).time()
datetime.time(0, 15)
2. Ordering naive and aware times
Same rule as datetime: == is False, < raises.
naive < aware
from datetime import time, UTC
time(12) < time(12, tzinfo=UTC)
TypeError: can't compare offset-naive and offset-aware times
both naive
from datetime import time
time(12) < time(12, 30)
True

When to use

Use it
  • Recurring times of day: opening hours, alarms, schedules
  • The wall-clock part of a datetime (dt.time())
Reach for something else
  • Durations → timedelta
  • A specific moment → datetime
  • Time zones with DST → a time alone cannot know which offset applies; use datetime + zoneinfo

Notes

CPython impl
PyDateTime_Time in Modules/_datetimemodule.c — 6 bytes of data, tzinfo, fold
Operators
Comparisons only (== < etc.) — no + or - with anything
Truth
Every time is truthy since Python 3.5; before that midnight UTC was falsy
repr
time repr lists tzinfo before fold; datetime repr lists fold before tzinfo

FAQ

Combine it with any date, add the timedelta, and take .time(): (datetime.combine(date.today(), t) + timedelta(minutes=45)).time(). Check the date part too if crossing midnight matters.