Search code examples
pythondatetimeeve

Nondeterministic behavior in python's relativedelta


I am trying to get a datetime seven days prior to another date.

So I am doing in the console:

import datetime
from dateutil.relativedelta import relativedelta

dt = datetime.date(2014, 10, 18)
dt_minus_one_week = datetime.date(2014, 10, 18) - relativedelta(days=7)

The result is, as expected, datetime.date(2014, 10, 11). However, I am running a webservice (using eve, but I think that this is unimportant) application for a long time, and then when I invoke the method to get the one week older date, I get datetime.date(2014, 10, 10). The code is exactly the same as above.

If I restart the app, the date is what I expected it to be. Why is this happening? Is relativedelta nondeterministic? Is there any way to "reset" it so I can get the right value again?


Solution

  • From the description of your functions in the comments, you have stepped on a common python "landmine".

    def get_d_minus_one_pacific_local_date():
        return datetime.datetime.now(
                pytz.timezone('US/Pacific')).date() - relativedelta(days=1)
    
    def get_relative_date(init=get_d_minus_one_pacific_local_date(), *args, **kwargs):
        return init + datetime.timedelta(*args, **kwargs)
    
    # ...
    get_relative_date(days=-7)
    

    When you set the default value of init in get_relative_date definition, it will not be recalculated again. So when the next day comes, it will use the value obtained at the time of function definition.

    See: https://stackoverflow.com/a/530768/632706