首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无效的日期解析器

无效的日期解析器
EN

Stack Overflow用户
提问于 2021-10-26 14:30:48
回答 2查看 64关注 0票数 2

有没有一种简单的方法可以将一个无效的日期减少到这个月的最后一个有效日期,比如“11月31日”?十一月三十一号不存在,因为十一月没有三十一天。

我正在处理的日期字符串非常混乱和不一致,所以我想避免尝试分割字符串或类似的东西。当日期不是无效的时候,Parser.parse()非常适合我的用例。

代码语言:javascript
复制
from dateutil import parser

datstrings_list = ["Nov 31, 1976", "11/31/76", "11/31/1976", "November 31st, 1976","1/32/1976"]

date_list = []

for i in datestrings_list:

    datestring = i

    date = parser.parse(datestring).date()

    date_list.append(date)

创建错误:

代码语言:javascript
复制
ParserError: day is out of range for month: Nov 31, 1976

Date_list的期望值:

代码语言:javascript
复制
[datetime.date(1976, 11, 30), datetime.date(1976, 11, 30),datetime.date(1976, 11, 30),datetime.date(1976, 11, 30), datetime.date(1/31/1976)]
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-10-26 14:51:28

您可以利用while循环并以这种方式完成它。

代码语言:javascript
复制
from dateutil import parser

datestring = "Nov 31, 1976"
date = None
while date is None:
    date_array = datestring.split()
    
    try:
        date = parser.parse(datestring).date()
    except parser._parser.ParserError:
        day = int("".join(x for x in date_array[1] if x.isdigit()))-1
        date_array[1] = f"{day},"
        datestring = f"{date_array[0]} {date_array[1]} {date_array[2]}"

print(date)

这应该可以满足您的需求。

问题更新:

代码语言:javascript
复制
from dateutil import parser
import calendar

datestrings_list = ["Nov 31, 1976", "11/31/76", "11/31/1976", "November 31st, 1976","1/32/1976"]
c = {month: index for index, month in enumerate(calendar.month_abbr) if month}

# Format string list
def standardise_list(date_list):
    lst = []
    for index, ls in enumerate(date_list):
        if "/" not in ls:
            ds = ls.split()
            if len(ds[0]) > 3:
                ds[0] = ds[0][:3]

            if len(ds[1]) > 2:
                ds[1] = ds[1][:2]

            nd = f"{c[ds[0]]}/{ds[1]}/{ds[2]}"
            lst.append(nd)
        else:
            lst.append(ls)
    return lst

# Fix out of range dates
def date_fix(datestring):
    date = None
    while date is None:
        date_array = datestring.split("/")
        
        try:
            date = parser.parse(datestring).date()
        except parser._parser.ParserError:
            day = int("".join(x for x in date_array[1] if x.isdigit()))-1
            date_array[1] = f"{day}"
            datestring = f"{date_array[0]} {date_array[1]} {date_array[2]}"
    return date

standard_string_list = standardise_list(datestrings_list)

dates = [date_fix(ds) for ds in standard_string_list]
print(dates)

>>> [datetime.date(1976, 11, 30), datetime.date(1976, 11, 30), datetime.date(1976, 11, 30), datetime.date(1976, 11, 30), datetime.date(1976, 1, 31)]
票数 2
EN

Stack Overflow用户

发布于 2021-10-26 14:44:42

我不确定是否有一种简单的方法可以将无效日期替换为该月的最大日期,但一种方法是使用calendar模块下的帮助器函数来获取给定月份和年份的最大日期:

代码语言:javascript
复制
import calendar

# Mapping of month abbreviation to month index. Ex: 'Jan': 1
month_indices = {month: i for i, month in enumerate(calendar.month_abbr)}

datestring = "Nov 31, 1976"

month_abbr, day, yr = datestring.replace(',', '').split()
last_day_in_month = calendar.monthrange(int(yr), month_indices[month_abbr])[-1]

assert last_day_in_month == 30

或者,如果您有像11/31/76这样的日期字符串,下面是如何获得该月和年的最大日期的方法:

代码语言:javascript
复制
datestring = "11/31/76"

month, day, year = map(int, datestring.split('/'))
# checking if we have abbreviation like `76` for year
# we have to make sure the year has 4 digits, otherwise `monthrange`
# appears to parse the year as `2076`, which is not what we want.
if year < 100:
    year += 1900

assert calendar.monthrange(year, month)[-1] == 30
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69725023

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档