0

I am attempting to build a program to handle alerts. I want it to be able to handle specific dates like 8/23/2015 7:00 and relative dates like 5 days and 7 hours from now. specific dates are fine but for relative dates if I try and just add 5 days and 7 hours to the date time it can overflow the values intended for that spot

import datetime
dt = datetime.datetime.now()
dayslater = 5
hourslater = 7
minuteslater = 30
alarmTime = datetime.datetime(dt.year, dt.month, dt.day + dayslater,
                              dt.hour + hourslater,
                              dt.minute + minuteslater, 0,0)

this is fine sometimes but if dayslater was 40 days it would overflow the value. I did set up a simple

if hours >= 24: 
    hours -= 24
    days++

however this won't work for overflowing months whose length in days isn't consistent.

0

2 Answers 2

3

Don't. Dates are hard, and it's very easy to get it wrong.

Instead, use timedelta:

In [1]: from datetime import datetime, timedelta

In [2]: dt = datetime.now()

In [3]: dt
Out[3]: datetime.datetime(2015, 7, 23, 15, 2, 55, 836914)

In [4]: alarmTime = dt + timedelta(days=5, hours=7, minutes=30)

In [5]: alarmTime
Out[5]: datetime.datetime(2015, 7, 28, 22, 32, 55, 836914)
Sign up to request clarification or add additional context in comments.

Comments

2

Use a datetime.timedelta() object and leave calculations to the datetime library:

import datetime

delta = datetime.timedelta(days=dayslater, hours=hourslater, minutes=minuteslater)
alarmTime = datetime.datetime.now() + delta

Demo:

>>> import datetime
>>> dt = datetime.datetime.now()
>>> dayslater = 5
>>> hourslater = 7
>>> minuteslater = 30
>>> delta = datetime.timedelta(days=dayslater, hours=hourslater, minutes=minuteslater)
>>> delta
datetime.timedelta(5, 27000)
>>> dt
datetime.datetime(2015, 7, 23, 21, 4, 59, 987926)
>>> dt + delta
datetime.datetime(2015, 7, 29, 4, 34, 59, 987926)

Note how the hours carried over to the next day (from 21:04 to 04:34), and thus the date went from the 23rd to the 29th. I did not have to worry about 'overflow' here.

This continues to work at month boundaries, at year boundaries, and in leap years, with February 29th:

>>> datetime.datetime(2015, 7, 26, 22, 42) + delta
datetime.datetime(2015, 8, 1, 6, 12)
>>> datetime.datetime(2015, 12, 26, 22, 42) + delta
datetime.datetime(2016, 1, 1, 6, 12)
>>> datetime.datetime(2016, 2, 23, 22, 42) + delta
datetime.datetime(2016, 2, 29, 6, 12)

1 Comment

Thanks this is a lot simpler. I'll accept the answer when stackoverflow lets me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.