Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'XX hours YY min ago' gives incorrect output #256

Open
hoonkai opened this issue Nov 26, 2020 · 1 comment
Open

'XX hours YY min ago' gives incorrect output #256

hoonkai opened this issue Nov 26, 2020 · 1 comment

Comments

@hoonkai
Copy link

hoonkai commented Nov 26, 2020

I'm trying to convert time strings containing 'ago' to datetime objects, but I'm getting incorrect results:

>>> import parsedatetime
>>> cal = parsedatetime.Calendar()
>>> cal.parseDT('11 hours 0 min ago')
(datetime.datetime(2020, 11, 26, 23, 56, 55), 2)
>>> cal.parseDT('11 hours ago')
(datetime.datetime(2020, 11, 26, 1, 57, 1), 2)

Does anyone know why '11 hours 0 min ago' and '11 hours ago' give different outputs?

Thanks

@tchar
Copy link

tchar commented Jul 24, 2021

Hey @hoonkai

Yeah I figured it out too. It seems like keywords like ago, before etc only apply to the last time keyword you enter.
11 hours 0 mins ago translates to + 11 hours - 0 minutes

11 hours ago translates to - 11 hours

basically take ago and put a minus in the last keyword you entered. If you want the exact results you need to put ago after ever keyword. Like 11 hours ago 0 minutes ago

Here is a reproducable example

>>> from datetime import datetime
>>> import parsedatetime as pdt
>>> cal = pdt.Calendar(version=pdt.VERSION_CONTEXT_STYLE)
>>> reference_date =  datetime(2021, 8, 12, 12, 0, 0)
>>> cal.parseDT('11 hours ago', sourceTime=reference_date)[0]
2021-08-12 01:00:00
>>> cal.parseDT('11 hours 0 minutes ago', sourceTime=reference_date)[0]
2021-08-12 23:00:00
>>> cal.parseDT('11 hours ago 0 minutes ago', sourceTime=reference_date)[0]
2021-08-12 01:00:00

What I did is replace these keywords and put ago in a timedelta like so:

import re
from datetime import datetime
import parsedatetime as pdt

def parse_with_ago(phrase, ref_dt):
    regex = r'\s(ago|before)(\s|$)'
    cal = pdt.Calendar(version=pdt.VERSION_CONTEXT_STYLE)
    phrase, did_have_ago = re.subn(regex, ' ', phrase)

    parsed, context = cal.parseDT(phrase, sourceTime=ref_dt)
    if did_have_ago == 0: # No ago or before detected
        return parsed

    # Ago or before detected
    td = parsed - ref_dt
    phrase = '{} days ago {} seconds ago'.format(td.days, td.seconds)
    parsed, context = cal.parseDT(phrase, sourceTime=ref_dt)
    return parsed

now = datetime(2021, 8, 12, 12, 0, 0)
date = parse_with_ago('11 hours 0 minutes ago', now)
print(date) # 2021-08-12 01:00:00

date = parse_with_ago('11 hours ago', now)
print(date) # 2021-08-12 01:00:00


date = parse_with_ago('1000 years ago', now)
print(date) # 1021-08-13 12:00:00

date = parse_with_ago('1000 years 0 months 0 days 0 hours 0 minutes 0 seconds ago', now)
print(date) # 1021-08-13 12:00:00

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants