Python 解析CSV文件时遇到问题,无法解析日期

Python 解析CSV文件时遇到问题,无法解析日期,python,csv,Python,Csv,我使用的是dateutil.parser.parse(date),它可以很好地处理单个日期,但问题是如果我有两天(即20/04/2032和05/04/1991),那么它将分别读取为4月20日和5月4日 我将在形式一致的专栏中阅读,但我不会提前知道专栏的形式,因为我希望从多个来源支持CSV 假设我有一个这样的列表(尽管实际上它们可能更大): [“01/02/2012”、“01/04/2012”、“01/05/2012”、“01/05/2012”、“01/25/2012”] [“01022012”、

我使用的是
dateutil.parser.parse(date)
,它可以很好地处理单个日期,但问题是如果我有两天(即
20/04/2032
05/04/1991
),那么它将分别读取为4月20日和5月4日

我将在形式一致的专栏中阅读,但我不会提前知道专栏的形式,因为我希望从多个来源支持CSV

假设我有一个这样的列表(尽管实际上它们可能更大):

  • [“01/02/2012”、“01/04/2012”、“01/05/2012”、“01/05/2012”、“01/25/2012”]
  • [“01022012”、“01042012”、“01052012”、“01052012”、“01252012”]
  • [“01/2nd/2012”等]
  • 通过查看列表,我可以确定
    01
    是月份,但我需要自动检查。我不能只检查大于
    12的数字,因为它可能意外地捕获年份子字符串

    我需要从中提取的数据是该月的前一天还是后一天。因此,当我稍后返回并再次解析字符串时,我知道要获取什么


    我似乎想不出一种干净有效的方法来执行此检查。

    如果您不知道格式,则无法解析。其实很简单。这两个(
    5/4/91
    5/4/1991
    )都将通过任何检查有效日期的检查;但是只有你知道它是5月4日还是4月5日,你也只能知道它的格式是什么

    最后,您最好希望的是一个有效的可解析日期列表,一个未解析(但可能是有效的)日期列表。然后,您必须手动检查这两个日期,以查看日期是否有意义

    要获取这些列表,请执行以下操作:

    try:
        maybe_valid.append(dateutil.parser.parse(some_date))
    except ValueError:
        probably_invalid.append(some_date)
    
    这是我提出的一个可能的路线图,看起来很合理?有任何重大缺陷或直接缺点吗?我需要一些帮助,将它转换成相对健壮的东西,因为它的目的是用于未知字符串


    然后我可以用{0,1,2}为年、月、日保留一个集合,然后返回给定元素(年、月、日)不可能的位置,并使用集合减法。如果任何集合到达{},则无法读取。如果任何一个集合的末尾有超过1个元素,我会根据优先级对日期/月份进行局部选择(任何一个集合都可能假设较低的方差为月份?)。如果只有一种组合,我会在以后读取日期时存储它,并将其传递给读者。

    我一直在尝试解决一些问题,但我不能只搜索特定的内容,因为日期可能完全是文本。日期中甚至可能没有分隔符,像122712这样的日期可能错误地表示该日期在该月之前和之后。您想如何解析1991年4月5日?如果您没有给出格式,有两种解析方法——4月5日或5月4日。您想如何解析010101?您必须为日期定义输入格式,或者必须定义优先级规则问题是我需要统一解析,但我不知道将遇到的文件格式。文件可以是MMDDYYYY或DDMMYYY或上述任何类型。它们中的任何一个都可能是amgibious的,所以我必须在解析它之前弄清楚它的格式是什么(或者如果有一种简单的方法可以随时检查的话)。问题是我不知道如何从datetime对象转换为“这就是它的显示方式”。是否保证列中的所有日期都具有相同的格式?如果你有希望(如果一个2位数的位置的值大于12->这是一天的位置),如果每一行都可以是不同的格式,你就被套住了。可以公平地假设列是一致的,但它可能不是整数(即“二十五”或“二十五”)因此,我不知道如何检查。我不太担心过于模糊的情况,即列中的每个日期都不明确。但是让我们假设我有1000个日期,999个是不明确的,但有一个显然是第一个日期。我怎样才能以干净高效的方式发现订单不含糊(以及它是什么)?你说的“先有日期”是什么意思?对不起,我指的是“先有日期”。和月前一天一样。最简单的检查是看前两位数是否大于12。同意Burhan的说法,你必须知道它的格式。无论是DD/MM/YYYY还是MM-DD-YY,你都必须知道这一点。如果它使用更多不同的格式(都是已知的),那么没有一行解决方案,可能需要一些变通方法才能使其工作。这有一个缺点,即不使用解析器,但优点是允许我知道各种元素位于哪个位置。我不确定这种方法对我的覆盖程度有多合理。
    # date is a string from the csv file.  
     if len(date) == 8 and all(isdigit(i) for i in date):  
    # then it's either the year comes first or last
    
        date = ["-".join([date[0:4], date[4:6], date[6:8])],
                "-".join([date[0:2], date[2:4], date[4:8])]
               ]
        # only one should be a possible date. if both are and the month
        # combinations don't sort it out then it's too ambigious anyway.
    
    # I'll do something similar for a string of 6 digits. but now I know that all
    # strings that are digits only are now seperated.
    # I'll also figure out which is the year (or make a reasonable guess and expand
    # the number to 8 and make the spaces).
    
    date = date.lower() # or an equivalent if it screws with symbols and numbers
    
    for month in full_length_month_list:
      if month in date:
            # I know I can parse this.
    
    for month in three_letter_month_list:
        if month in date:
            # I know I can parse this.
    
    month_days = {'first':01, 'second':02, 'third':03, ... ,'thirty first': 31}
    for string, number in month_days:
        date.replace(string,number)
    
    for shorthand in ['st','nd','rd','th']:
        date.replace(shorthand, '')
    
    date.replace('the','')
    
    # Then I use a regex matcher to get 3 sets of digits: The longest set is the 
    # year. The shortest two sets are either date or month. I can get the order
    # based on the matcher. Then I can figure out by looping through if there is
    # ever a date greater than 12. If so I know the order. I can also possibly
    # track the replacements maybe. So that if jan/january was in the original
    # string I already know anyway.