2016-07-04 2 views
0

Скажем, у меня есть список дат, которые отформатированы в одном из пяти способов ниже:Более эффективный способ форматирования дат для в Python для MySQL

Date_Type_1 = 2001 Apr 15 
Date_Type_2 = 2001 Apr 
Date_Type_3 = 2000 Spring 
Date_Type_4 = 2000 Nov-Dec 
Date_Type_5 = 2001 

Так что мой список дата будет выглядеть следующим образом.

Date_list = ["2001 Apr 15", "2004 May 15", "2011 Jan", "2011 Fall", "2000 Nov-Dec", "2012", "2000 Spring" ] 

Теперь я хочу попробовать и отформатировать эти даты, чтобы они могли быть переданы в базу данных MySQL. Единственный способ, которым я знаю, как использовать большой поток условий. Вот пример того, как я это сделаю. Я не буду включать ВСЕ условия, так как это займет слишком много места.

for i in Date_list: 
    year = i[:4] 
    #This will be my conditional logic to define a month. 
    #This is only an example. Will not include all 12 months, 4 seasons, and various bi-months 
    if "Apr" in i and "Mar-Apr" not in i: 
    month = 4 
    if "Mar-Apr" in i: 
    month = 3 
    if "May" in i and "May-Jun" not in i: 
    month = 5 
    if "Apr-May" in i: 
    month = 4 
    if "Spring" in i: 
    month = 3 
    #This will be conditional logic to define the day. 
    #I would do this for each of the 31 days of the month. 
    if "15" in i and "2015" not in i: 
    day = 15 

date_return = datetime.datetime(year,month,day) 
date_format = date_return.date().isoformat 

Проблема в том, что я делаю ряд предположений. Я в порядке с определением сезонов «Весна/Лето ..», и двухмесячный (например, Мар/Апр) возвращается в виде конкретных месяцев. Вопрос, по крайней мере, задающих дней он не поймает дней, если:

test_list = [2011 May, 2015 Apr 15] 
for i in test_list: 
    if "15" in i and "2015" not in i: 
    day = 15 

Это не будет ловить день. Мне интересно, есть ли более эффективный способ сделать это? Для этого текущего метода потребуется 50 + условных операторов для определения дня/месяца.

+0

Я не думаю, что ваш код медленный, но выглядит как ваша эффективная средняя короче версия. – YOU

+1

Оба они являются отличными ответами и очень изящными. Спасибо, я бы хотел выбрать оба. – Sean

ответ

1

Вы должны использовать обычный модуль re выражений Python. Для этого намного лучше, чем пытаться возиться со срезами и in.

import re 

MONTHS = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 
    'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] 
SEASONS = { 'Spring': 'Mar', 'Summer': 'Jun', 'Fall': 'Sep', 
    'Autumn': 'Sep', 'Winter': 'Dec' } 

_MONTHS_RE = '|'.join(MONTHS) 
_SEASONS_RE = '|'.join(SEASONS) 
DATE_RE = re.compile(r"""(?ax) # ASCII-only verbose mode 
    (?P<year>20[0-9]{2}) # Year 
    (# followed by either... 
     (?P<month>""" + _MONTHS_RE + r""") # a month name then... 
     ( -(?P<endmonth>""" + _MONTHS_RE + r""") # a month range 
     | (?P<day>[1-9][0-9]?) # a day number 
     )? # range and day are optional 
    | (?P<season>""" + '|'.join(SEASONS) + r""") # or a season. 
    )""") 

def parse_date(datestr): 
    m = DATE_RE.match(datestr) 
    if m is None: 
     return # Didn't match 
    md = m.groupdict() 
    year = int(md["year"]) 
    if "season" in md: 
     month = SEASONS[md["season"]] 
    else: 
     month = md["month"] 
     if "endmonth" in md: 
      # handle month range here. 
     day = int(md.get("month", 1)) 
    return year, month, day 
    # Month is returned as a string; to get a number, use: 
    return year, MONTHS.index(month) + 1, day 

Обратите внимание, что это не гарантирует, что дата существует; он примет "2099 Jun 50" или много других плохих дат. Но я оставлю фильтрацию в качестве упражнения для читателя.

1

Я думаю, что вы можете сделать это следующим образом:

>>> import datetime 
>>> dates = ["2001 Apr 15", "2004 May 15", "2011 Jan", "2011 Fall", "2000 Nov-Dec", "2012", "2000 Spring" ] 
>>> 
>>> def convert(date_str): 
...  tokens = date_str.split(' ') 
...  if len(tokens) == 1: 
...   date_time = datetime.datetime.strptime(date_str, '%Y') 
...  elif len(tokens) == 3: 
...   date_time = datetime.datetime.strptime(date_str, '%Y %b %d') 
...  elif len(tokens) == 2 and '-' in tokens[1]: 
...   date_str = date_str.split('-')[0] 
...   date_time = datetime.datetime.strptime(date_str, '%Y %b') 
...  else: 
...   seasons = { 
...    'spring': 'Mar', 
...    'fall': 'Sep', 
...   } 
...   if tokens[1].lower() in seasons.keys(): 
...    date_str = '{} {}'.format(tokens[0], seasons[tokens[1].lower()]) 
...   date_time = datetime.datetime.strptime(date_str, '%Y %b') 
...  return date_time.date().isoformat() 
... 
>>> 
>>> for date_str in dates: 
...  print '{} === {}'.format(date_str, convert(date_str)) 
... 
2001 Apr 15 === 2001-04-15 
2004 May 15 === 2004-05-15 
2011 Jan === 2011-01-01 
2011 Fall === 2011-09-01 
2000 Nov-Dec === 2000-11-01 
2012 === 2012-01-01 
2000 Spring === 2000-03-01 
Смежные вопросы