1

I'm using dateparser to parse strings and return a date value to compare against an extraction date then return an integer value as the difference between the two. In some cases, the parsed date is a range, in which case I average the two ends of the range and get the difference between the average and the extraction date.

I'm having trouble replacing the year as 2021 when the month rolls into next year, so my differences are all negative. How can I replace the year with 2021?

Example Output:

extraction date:  10/26/2020 0:00;   promo_message: ["Arrives: Feb 26 - March 2"] ;                   first_delivery:   -243  ;     last_delivery:  -238   ;   delivery:   -240

Code:

            elif 'Arrives' in row[6] and '-' in row[6]:
                try:
                    example_2 = promo_message.split('-',1)
                    first_delivery = (parse(example_2[0], fuzzy=True))
                    if first_delivery.month == 1:
                        first_delivery = first_delivery.replace(month=1, year=2021, tzinfo=None)
                    elif first_delivery.month == 2:
                        first_delivery = first_delivery.replace(month=2, year=2021, tzinfo=None)
                    elif first_delivery.month == 3:
                        first_delivery = first_delivery.replace(month=3, year=2021, tzinfo=None)
                    first_delivery = (parse(example_2[0], fuzzy=True))
                    first_delivery_int = (first_delivery - extraction_date).days

                    second_delivery = (parse(example_2[1], fuzzy=True))
                    if second_delivery.month == 1:
                        second_delivery = second_delivery.replace(month=1, year=2021)
                    elif second_delivery.month == 2:
                        second_delivery = second_delivery.replace(month=2, year=2021)
                    elif second_delivery.month == 3:
                        second_delivery = second_delivery.replace(month=3, year=2021)


                    second_delivery = (parse(example_2[1], fuzzy=True))
                    second_delivery_int = (second_delivery - extraction_date).days
Adam Kern
  • 566
  • 4
  • 14
GiltLorn
  • 11
  • 2

2 Answers2

0

Why are you doing some form of jury-rigged date manipulation? If you are getting the dates in some format that you know, then parse that and create datetime objects. Once you have datetime objects, it's trivial to do date manipulation based on the methods in there.

PJacobs
  • 23
  • 3
0

Using replace(year=2021) is the right idea, but it might be easier if you use the extraction_date to change the year. Then you could do something like this:

from dateutil.parser import parse

def average_diff(extraction_date, promo_msg):
    split_date = promo_msg.split("-", 1)
    first_delivery = parse(split_date[0], fuzzy=True)
    second_delivery = parse(split_date[1], fuzzy=True)

    # Check for year rollover
    if first_delivery < extraction_date:
        first_delivery = first_delivery.replace(year=extraction_date.year + 1)
        second_delivery = second_delivery.replace(year=extraction_date.year + 1)

    diff1 = (first_delivery - extraction_date).days
    diff2 = (second_delivery - extraction_date).days
    
    # Deal with integer days, so use integer division
    return (diff1 + diff2) // 2

There is a key assumption here that extraction_date is also a datetime object (not a date object). If it's also the result of dateutil.parser's parse function then you should be fine. Now this code isn't dependent on the year, month, or even day in question.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Adam Kern
  • 566
  • 4
  • 14
  • For sure - I just realized that you may want to only check if `first_delivery < extraction_date`. What if the extraction date was in June, the first delivery date is May of the following year, and the second extraction date was July of the following year? You'd end up with the wrong answer. Presumable, if the `first_delivery` is before `extraction_date`, the year of both delivery dates needs to change. Similarly, if the delivery dates span a year (i.e. extraction in June, first in December, second in January), you'd have to check that as well. – Adam Kern Nov 03 '20 at 19:54
  • Also, if this is an acceptable answer, would you mind marking it as accepted so others can more easily find it? – Adam Kern Nov 04 '20 at 03:51