scrapinghub / dateparser

python parser for human readable dates
BSD 3-Clause "New" or "Revised" License
2.56k stars 465 forks source link

dateparser.search_dates OverflowError: date value out of range with Russian text and settings={'PREFER_DATES_FROM': 'past'} #1194

Open Buratinator opened 1 year ago

Buratinator commented 1 year ago

dateparser version: 1.1.8 Python version: 3.12.0

When searching for dates in a large chunk of Russian text (see example below) with the 'PREFER_DATES_FROM': 'past' setting, dateparser throws the OverflowError: date value out of range error.

Additional observations:

  1. The error is not thrown if the string is modified in certain ways, specifically, if some text with numbers or date-related terms is removed. E.g. in the example below, if the last word is deleted or modified (среду - meaning Wednesday), the code works fine. Removing other chunks from the string also prevents the error from being thrown.
  2. Also, changing the 'PREFER_DATES_FROM' setting to 'future' or removing it altogether also prevents the error from happening.

Code to reproduce (the text makes no sense as I minimized the size of string as much as I could to still be able to reproduce the error):

from dateparser.search import search_dates

some_text = '''Хроника time_stated_uk Отправлено в  13:56 13:56 FT: произральская 
начала вторжения России в Украину в 2022 году западные страны пытались достичь консенсуса 
post Copy this link Подробнее об этих ссылках Отправлено в  13:00 13:00 Срочно Путин: 
этих ссылках Отправлено в  11:56 11:56 В Курской области 18 дронов попали в лагерь военных 
у аэродрома «Халино», утверждают в СБУ Атаку дронов на Курскую область в ночь на среду 
opy this link Подробнее об этих ссылках Отправлено в  11:10 11:10 Женщина погибла в 
в  10:52 10:52 Последствия ночного удара по Запорожью: фото t.me/pgo_gov_ua Copyright: 
t.me/pgo_gov_ua В ночь на среду по нескольким районам Запорожья было нанесено шесть 
Подробнее об этих ссылках Отправлено в  10:03 10:03 New York Times: Украина получила 
проблемы с бюджетом — каждая такая ракета стоит около 1,5 млн долларов.  В итоге Остин 
в  9:02 9:02 Сторонник Трампа и противник помощи Украине Джим Джордан пока не смог стать 
this link Подробнее об этих ссылках Отправлено в  8:53 8:53 Путин выступил в Китае и 
ссылках Отправлено в  7:50 7:50 Интенсивность российских атак в районе Авдеевки 
украинские позиции в Авдеевки и вокруг нее пять раз.  До этого, с 10 октября, когда 
российские войска пошли в наступление в районе Авдеевки, и до 16 октября украинский 
генштаб сообщал о 15 и более атаках в сутки. В предыдущие сутки их было 10.  В то же 
этих ссылках Отправлено в  6:52 6:52 Срочно Минобороны России заявило о 28 сбитых 
беспилотниках Министерство обороны России утверждает, что в ночь на среду российская 
Гладков сообщил о шести сбитых дронах над его регионом. 15 октября Минобороны России 
в  6:46 6:46 ISW: появление у Украины ATACMS может повлиять на эффективность действий 
в  5:34 5:34 В районе Белгорода ночью были сбиты шесть беспилотников — губернатор 
в ночь на среду'''

found_dates = search_dates(some_text, settings= { 'PREFER_DATES_FROM': 'past' })
BearGaming commented 10 months ago

I'm new to open-source but I've noticed after some debugging that the error is being caused due to the following lines specifically this portion:

    if days[day_index] == day:
            if self.settings.PREFER_DATES_FROM == "past": 
                steps = 7    # Too large if dateobj.month & dateobj.year are at their minimum value of 1
            else:
                steps = 0
    else:
        while days[day_index] != day:
            day_index -= 1
            steps += 1
   delta = timedelta(days=-steps)
dateobj = dateobj + delta    # This is the offending line

After the if statement steps = 7 (which only runs if PREFER_DATES_FROM, hence it's behavior), if dateobj.day < 7 and dateobj.month and datetobj.year are their minimum value of 1, when the line dateobj = dateobj + delta is run, dateobj, will have a year attribute below it's allowed minimum. According to the datetime documentation this results in the Overflow Error and explains the message "date value out of range" as dateobj wants it's year attribute to be between dateobj,min and dateobj.max.

Notably, all these conditions (days attribute value less than 7, months & years attribute set to 1 and days[day_index] == day) seems to only occur for the very last instance of "среду" (Wednesday) as stepping through the debugger, it seems all these conditions dont line up for the other parsed items. I'm not familiar enough with the codebase to tell why this is but I found that the steps = 7 line came in #559