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.
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
| Name | Type | Required | Description |
|---|---|---|---|
| hour | int | no (0) | 0 to 23. |
| minute | int | no (0) | 0 to 59. |
| second | int | no (0) | 0 to 59. |
| microsecond | int | no (0) | 0 to 999999. |
| tzinfo | tzinfo | None | no (None) | Usually None. With a fixed-offset timezone the time is aware. |
| fold | int | no (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
True4. Compare
from datetime import time
time(9) < time(17, 30)
Returns
True5. 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
TruePitfalls
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.