使用Python中的parsedatetime库,是否可以将日期限制为当前年份?

时间:2014-08-01 22:47:46

标签: python parsing

使用parsedatetime,我想将Jan 1之类的值传递给日历解析器并让它返回当前年度的1月1日(其中,正如我发布的那样,将是2014-01-01)。

默认情况下,parsedatetime返回日期的 next 次出现(即2015-01-01):

>>> import parsedatetime as pdt
>>> from datetime import datetime
>>> from time import mktime
>>> cal = pdt.Calendar()
>>> datetime.now()
datetime.datetime(2014, 8, 1, 15, 41, 7, 486294)
>>> str(datetime.fromtimestamp(mktime(cal.parse('Jan 1')[0])))
'2015-01-01 14:41:13'
>>> str(datetime.fromtimestamp(mktime(cal.parse('Dec 31')[0])))
'2014-12-31 14:41:17'

我尝试了last Jan 1Jan 1 this year等输入但没有成功。

有没有办法告诉解析器返回当前年份的值?


编辑以添加一些未在原始问题中指定的要求:

  • 支持自然语言处理(这就是我使用parsedatetime的原因)
  • 不会影响其他解析时解析功能(例如除当前和值之外的其他年份,例如yesterday6 months before 3/1

6 个答案:

答案 0 :(得分:3)

在这里承担 - 不知道如何获取原始的SO配置文件,因为我以前使用ClaimID ...

anywho - 你可以设置一个标志,使解析时间在解析只有月/日值的时候永远不会前进一年......

import parsedatetime as pdt
ptc = pdt.Constants()
ptc.YearParseStyle = 0

cal = pdt.Calendar(ptc)
print cal.parse('Jan 1')
# ((2014, 1, 1, 15, 57, 32, 5, 214, 1), 1)

答案 1 :(得分:2)

parse函数似乎带有sourceTime参数,您可以将其设置为当前年份的第1个。

请参阅https://bear.im/code/parsedatetime/docs/index.html

答案 2 :(得分:1)

我会替换你的datetime对象上的年份。例如:

str(datetime.fromtimestamp(mktime(cal.parse('Dec 31')[0])))

会变成:

str(datetime.fromtimestamp(mktime(cal.parse('Dec 31')[0])).replace(year=datetime.today().year))

答案 3 :(得分:0)

如果你不喜欢使用那个库(也许你是?),你可以这样做:

>>> import datetime
>>> datetime.datetime.now().replace(month=1, day=1).strftime("%Y-%m-%d %H:%M:%S")
'2014-01-01 22:55:56'
>>>

答案 4 :(得分:0)

from datetime import date, datetime

d = datetime.strptime('Jan 1', '%b %d')
d = date(datetime.now().year, d.month, d.day)

datetime.date(2014, 1, 1)提供d,然后您可以使用

进行格式化
print d.strftime('%Y-%m-%d')

2014-01-01

答案 5 :(得分:0)

基于Bear's answer的改进实施。

同样,这受到以下事实的限制:由于这是在另一个DSL解析器中实现的,natural_date只能接受一个字符串:

import parsedatetime as pdt
from datetime import datetime, date, timedelta
from time import mktime


def natural_date(human_readable):
    human_readable = human_readable.lower()

    # Flag to cause parsedatetime to never go forward
    # https://stackoverflow.com/a/25098991/1093087
    ptc = pdt.Constants()
    ptc.YearParseStyle = 0
    cal = pdt.Calendar(ptc)

    result, parsed_as = cal.parse(human_readable)

    if not parsed_as:
        raise ValueError("Unable to parse %s" % (human_readable))

    return date.fromtimestamp(mktime(result))


def test_natural_date():
    cases = [
        # input, expect
        ('jan 1', date(date.today().year, 1, 1)),
        ('dec 31', date(date.today().year, 12, 31)),
        ('yesterday', date.today() - timedelta(days=1)),
        ('3 months before 12/31', date(date.today().year, 9, 30))
    ]

    for human_readable, expect in cases:
        result = natural_date(human_readable)
        print("%s -> %s" % (human_readable, result))
        assert result == expect, human_readable


test_natural_date()

同样感谢Mark Ransom,unearthed sourceTime parameter提供了解决此问题的另一种方法,尽管该解决方案因this issue而变得复杂。