89

I'm trying to do something like this:

time() + timedelta(hours=1)

however, Python doesn't allow it, apparently for good reason.

Does anyone have a simple work around?

Related:

Community
  • 1
  • 1
Antonius Common
  • 2,791
  • 5
  • 31
  • 32

5 Answers5

149

The solution is in the link that you provided in your question:

datetime.combine(date.today(), time()) + timedelta(hours=1)

Full example:

from datetime import date, datetime, time, timedelta

dt = datetime.combine(date.today(), time(23, 55)) + timedelta(minutes=30)
print dt.time()

Output:

00:25:00
jfs
  • 374,366
  • 172
  • 933
  • 1,594
  • 8
    It feels a bit like a work-around to enhance the data by irrelevant information. What happens if `today()` is the day before switching to daylight saving times, and the timedelta extends into the different time zone? Is this code affected by locales? – bluenote10 Apr 04 '17 at 20:46
  • 1
    @bluenote10 a naive datetime object is just an integer number of microseconds that is broken-down according to the proleptic Gregorian calendar. In other words, the code in the answer works as is even around, during DST transitions in any local timezone. `date.today()` is used to support both positive and negative timedeltas. `date.min` would work for positive timedeltas. – jfs Apr 05 '17 at 07:03
  • @J.F.Sebastian: That's reassuring, thanks for the update. It still makes me cringe if a function that is supposed to be pure has a side effect. People from the year 9999 will not like this either ;). – bluenote10 Apr 05 '17 at 07:11
  • 3
    @bluenote10 Practicality beats purity. I doubt `datetime.MAXYEAR` will remain 9999 in 9999. – jfs Apr 05 '17 at 07:31
13

If it's worth adding another file / dependency to your project, I've just written a tiny little class that extends datetime.time with the ability to do arithmetic. If you go past midnight, it just wraps around:

>>> from nptime import nptime
>>> from datetime import timedelta
>>> afternoon = nptime(12, 24) + timedelta(days=1, minutes=36)
>>> afternoon
nptime(13, 0)
>>> str(afternoon)
'13:00:00'

It's available from PyPi as nptime ("non-pedantic time"), or on GitHub: https://github.com/tgs/nptime

The documentation is at http://tgs.github.io/nptime/

rescdsk
  • 8,478
  • 4
  • 34
  • 32
8

Workaround:

t = time()
t2 = time(t.hour+1, t.minute, t.second, t.microsecond)

You can also omit the microseconds, if you don't need that much precision.

sth
  • 211,504
  • 50
  • 270
  • 362
  • yes, nice answer. I should have made it trickier, like: time() + timedelta(minutes=30) – Antonius Common Mar 17 '09 at 22:50
  • 7
    If `t == time(23,59)` then this approach won't work. When you add `1` to `t.hour` you'll get `ValueError: hour must be in 0..23` – jfs Mar 17 '09 at 23:20
  • Corrected the syntax error. For the 23:59 case the question is what the real intention of the calculation is, what you really want to get as a result in that case. I assumed it should stay on the same day (or give an error), else you usually would have datetime in the first place... – sth Mar 17 '09 at 23:55
  • 1
    This method caused an error for me because I was adding 1 day to October 31. It is for this reason that you should use `datetime.timedelta(days=1)` to add a day to a datetime object. You will avoid debug land. – Bobort Oct 31 '16 at 13:44
  • Although this answer is missing critical information, I think it is the best "default" approach. The other answers are also missing critical information, but instead of an error, they have the implicit "overflow" to the next/previous date, which could be even more critical (hidden bug that is hard to find). In my use case specifically, that is not what I want, I'd like to have `time.max` if I'm trying to add 1 hour to `t == time(23, 59)`, for example. – felipou Jan 08 '22 at 01:39
7

This is a bit nasty, but:

from datetime import datetime, timedelta

now = datetime.now().time()
# Just use January the first, 2000
d1 = datetime(2000, 1, 1, now.hour, now.minute, now.second)
d2 = d1 + timedelta(hours=1, minutes=23)
print d2.time()
Ali Afshar
  • 39,783
  • 12
  • 90
  • 108
  • 1
    +1: for `datetime` module. Otherwise it would require to deal with Overflow errors and such manually. – jfs Mar 17 '09 at 23:25
4

You can change time() to now() for it to work

from datetime import datetime, timedelta
datetime.now() + timedelta(hours=1)
duhaime
  • 23,078
  • 13
  • 147
  • 194
yiming
  • 59
  • 4