为 Python for MySQL 格式化日期的更有效方法
More Effecient Way to Format Dates for in Python for 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 数据库。我知道的唯一方法是使用大量条件流。这是我将如何执行此操作的示例。我不会包括所有条件,因为它会占用太多 space.
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
这个问题是我做了一些假设。我可以将季节 "Spring/Summer.." 和双月刊(例如 Mar/Apr)returns 定义为特定月份。问题是,至少在定义天数时,如果出现以下情况,它就不会赶上天数:
test_list = [2011 May, 2015 Apr 15]
for i in test_list:
if "15" in i and "2015" not in i:
day = 15
今天赶不上。我想知道是否有更有效的方法来做到这一点?此当前方法需要 50 多个条件语句来定义 day/months.
我想你可以这样做:
>>> 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
您应该使用 Python 正则表达式模块 re
。这比试图弄乱切片和 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"
或许多其他错误日期。但我会将过滤作为 reader.
的练习。
假设我有一个按以下五种方式之一格式化的日期列表:
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 数据库。我知道的唯一方法是使用大量条件流。这是我将如何执行此操作的示例。我不会包括所有条件,因为它会占用太多 space.
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
这个问题是我做了一些假设。我可以将季节 "Spring/Summer.." 和双月刊(例如 Mar/Apr)returns 定义为特定月份。问题是,至少在定义天数时,如果出现以下情况,它就不会赶上天数:
test_list = [2011 May, 2015 Apr 15]
for i in test_list:
if "15" in i and "2015" not in i:
day = 15
今天赶不上。我想知道是否有更有效的方法来做到这一点?此当前方法需要 50 多个条件语句来定义 day/months.
我想你可以这样做:
>>> 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
您应该使用 Python 正则表达式模块 re
。这比试图弄乱切片和 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"
或许多其他错误日期。但我会将过滤作为 reader.