有没有一种简单的方法可以将一个无效的日期减少到这个月的最后一个有效日期,比如“11月31日”?十一月三十一号不存在,因为十一月没有三十一天。
我正在处理的日期字符串非常混乱和不一致,所以我想避免尝试分割字符串或类似的东西。当日期不是无效的时候,Parser.parse()非常适合我的用例。
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)创建错误:
ParserError: day is out of range for month: Nov 31, 1976Date_list的期望值:
[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)]发布于 2021-10-26 14:51:28
您可以利用while循环并以这种方式完成它。
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)这应该可以满足您的需求。
问题更新:
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)]发布于 2021-10-26 14:44:42
我不确定是否有一种简单的方法可以将无效日期替换为该月的最大日期,但一种方法是使用calendar模块下的帮助器函数来获取给定月份和年份的最大日期:
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这样的日期字符串,下面是如何获得该月和年的最大日期的方法:
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] == 30https://stackoverflow.com/questions/69725023
复制相似问题