我有一个小项目,我把日期非正式地写在firebase数据库中作为字符串我需要将这些日期转换为日期时间格式。这是假设日期是有效的网站的输入不能修改(这是解决这个问题的全部前提)。还假设月份是按名称写的,月份是按yyyy格式写的。
我对这些条目的一些示例进行了分类:
几乎明确:
“2017年7月13日”、“2008年12月3日”、“2016年12月”、“2017年12月21日”、“2020年”、“2017年11月24日”、“2012年3月14日”、“2016年7月22日”、“2012年2月20日”、“2011年1月17日”、“2013年7月获得”……
这将相对容易。年份总是4位数字,日期是2位数字,月份是字符串。这些可以检查/比较,如果它们错过了确切的日期(1或2位数字),我可以假设它可以放在第一个(一个月的第一天),没有指定的月份(假设是一月份)。
其他简单的字符串:
当组准备就绪时,“未指定”、“已取消”、“已设置”。
这些没有日期,所以它们不重要。只查不到号码就能搞定。这些可以设置为00-00-0000,无所谓。
更难的:
“在12或24个月内”、“2013年第4季度”、“2019年深秋”
我在想:
如果我读“within”,我计算当前日期,加上它后面的数字(天、月、年)。
如果我把q(四分之一)定义为一张地图Q={1:(1,2,3), 2:(4,5,6), 3:(7,8,9), 4:(10,11,12)}
还有那些话
when = {"Early" : 1, "Mid": 2, "Late": 3}
季节也一样。
例如,我可以访问第四季度的Q的第四个元素,得到它的月份,或者将晚春作为季节[“春天”]并得到“早、中、晚”的月份。
回到问题上来:
我不确定我是否应该使用正则表达式、映射和如此多的比较来处理这个问题,这样会引入很多错误,或者使用某种人工智能,但是我还不太精通这个主题。
那么,回到问题上来,你会如何处理这类问题?
有什么图书馆可以帮忙吗?
我觉得这里没有一个非常简单的实现,或者我知道的方法效率低下,需要大量的硬编码。
最佳答案
我就是这么做的。万一有人需要解决这样的问题。
这段代码可以优化,但我只是没有时间自动柜员机。
假设:日期格式为[任何内容]DD[任何内容]month(书面形式)[任何内容]YYYY
假设:如果未指定日期,则首选数字1。几个月都一样。
import re
def validate_date(d,m,y):
leap = False
valid = False
y = int(y)
d = int(d)
m = int(m)
if(y % 400 == 0):
leap=True
if(y % 100 == 0):
leap = False
if(y % 4 == 0):
leap = True
if (m<13):
if (m == 1 | m==3 | m== 5 | m==7 | m==8 | m==10 | m==12 ):
if (d <=31):
valid=True
if (m == 4 | m==6 | m==9 | m==11 ):
if (d <= 30):
valid = True
if (m==2):
if (leap == True):
if (d <= 29):
valid = True
if (leap == False):
if (d <= 28):
valid = True
return valid
months = {
1: "januari",
2: "februari",
3: "mars",
4: "april",
5: "maj",
6: "juni",
7: "juli",
8: "augusti",
9: "september",
10: "oktober",
11: "november",
12: "december"
}
def validate(date):
month=0
day=0
year=0
raw_date = str(date)
#get the integers in the text
raw_date = raw_date.lower()
if (not ("q1" in raw_date or "q2" in raw_date or
"q3" in raw_date or "q4" in raw_date)):
if (len(re.findall('\d+', raw_date))==2):
day, year = map(int, re.findall('\d+', raw_date))
elif (len(re.findall('\d+', raw_date))==3):
day, month, year = re.findall('\d+', raw_date)
else:
if (len(re.findall('\d+', raw_date))==2):
quarter, year = map(int, re.findall('\d+', raw_date))
day = 1
#Set month to the string found, if any.
if (month==0):
if (months.get(1) in raw_date or ("q1" in raw_date)): month = 1
elif(months.get(2) in raw_date): month = 2
elif(months.get(3) in raw_date): month = 3
elif(months.get(4) in raw_date or ("q2" in raw_date)): month = 4
elif(months.get(5) in raw_date): month = 5
elif(months.get(6) in raw_date): month = 6
elif(months.get(7) in raw_date or ("q3" in raw_date)): month = 7
elif(months.get(8) in raw_date): month = 8
elif(months.get(9) in raw_date): month = 9
elif(months.get(10) in raw_date or ("q4" in raw_date)): month = 10
elif(months.get(11) in raw_date): month = 11
elif(months.get(12) in raw_date): month = 12
else: month = 1
clean_date = str(str(day)+"-"+str(month)+"-"+str(year))
# print (clean_date)
if (validate_date(day,month,year)==False): return "00-00-0000"
else: return str(clean_date)