【问题标题】:Input string recognise text and return date parse输入字符串识别文本并返回日期解析
【发布时间】:2020-11-25 09:37:49
【问题描述】:

我有一个字符串输入,其中文本包含数据为“下个月的星期一”或“新年前 4 天”需要转换为日期,假设今天是 25/11/2020,所以下个月星期一是 07/ 12/2020,那么我应该如何在 python 中做到这一点(我尝试使用 datetime、dateutil 但没有帮助')

next week saturday
4 days before new year
3 days after new year
second wednesday of next month

我需要输出为

05/12/20
28/12/20
03/01/21
09/12/21

尝试阅读文档,但没有帮助任何人都可以对此有所了解。

这是我的 python 代码。

from datetime import datetime, timedelta
from dateutil import parser
from dateparser.search import search_dates
# Create your views here.

def converter_view(request):
    form = DateStringForm()
    if request.method == 'POST':
        form = DateStringForm(request.POST)
        if form.is_valid():
            input_string = form.cleaned_data['string_date']
            list_of_dates = []
            if input_string.lower() == "today":
                data = datetime.now()
                list_of_dates.append(data.strftime('%d/%m/%Y'))
            elif input_string.lower() == "tomorrow":
                data = datetime.now() + timedelta(1)
                list_of_dates.append(data.strftime('%d/%m/%Y'))
            elif input_string.lower() == "yesterday":
                data = datetime.now() - timedelta(1)
                list_of_dates.append(data.strftime('%d/%m/%Y'))
            else:
                try:
                    # Using search_dates method we were extracting the keywords related to date, day or month
                    # So search_dates is going to return a "list of tuple" where 0th index is string and 1st is datetime
                    data = search_dates(input_string)
                except Exception as msg:
                    print('Exception :', msg)
                else:
                    try:
                        for i in data:
                            # So as we require to convert that date back in string format, we parse the extracted data in data
                            # where parser.parse() is taking 0th index which is string, and converting it to date and by using
                            # strftime function we get the required format
                            list_of_dates.append(parser.parse(i[0]).strftime('%d/%m/%Y'))
                            print(list_of_dates)
                    except TypeError as msg:
                        print("String does not contain any day or dates")
            values = DateStringConvert(string_date=input_string, date=list_of_dates)
            values.save()
            return HttpResponseRedirect('/dateconverter')
    return render(request, 'DateTimeConverter/index.html', {'form':form})

【问题讨论】:

  • 示例是所有可能的格式吗?因为您必须手动对每个选项进行编程(不幸的是)。
  • @GijsWobben 不,这取决于用户想要提供什么,这些只是样本。

标签: python django python-datetime date-parsing python-dateutil


【解决方案1】:

不可能促进所有可能的组合和文本片段。但是,您可以使用一些基本模式涵盖大多数情况。

import re
import datetime

queries = [
    "next week saturday",
    "4 days before new year",
    "3 days after new year",
    "second wednesday of next month",
]

def parse_relative_string_date(text: str, start_date: datetime.datetime = datetime.datetime.now()) -> datetime.datetime:

    def _next_week(weekday: str):
        weekdays = {
            "monday": 0,
            "tuesday": 1,
            "wednesday": 2,
            "thursday": 3,
            "friday": 4,
            "saturday": 5,
            "sunday": 6,
        }
        next_week = start_date + datetime.timedelta(weeks=1)
        return next_week + datetime.timedelta((weekdays[weekday.lower()] - next_week.weekday()) % 7)

    def _new_year(n_days: str, direction: str):
        new_years = datetime.datetime(year=start_date.year + 1, month=1, day=1)
        directions = {
            "before": -1,
            "after": 1,
        }
        return new_years + datetime.timedelta(directions[direction.lower()] * int(n_days))

    patterns = {
        r"next week (?P<weekday>\w+)": _next_week,
        r"(?P<n_days>\d+) days (?P<direction>\w+) new year": _new_year,
        # Add more patterns here
    }

    for pattern, callback in patterns.items():
        found = re.search(pattern, text)
        if found is not None:
            return callback(**dict(found.groupdict()))


for query in queries:
    print(parse_relative_string_date(query))

【讨论】:

  • 谢谢@GijsWobben,你太棒了,现在很感激我终于知道了如何制作它,但正如你所说,这也是真的,很难为所有人提供便利,再次感谢
猜你喜欢
  • 1970-01-01
  • 2019-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多