将月份年份对解析为日期时间
假设我有两个字符串,分别是 'Jan-2010' 和 'Mar-2010',我想把它们解析成两个日期对象:1-Jan-2010 和 31-Mar-2010(也就是最后一天)。
在Python中,最好的方法是什么呢?我应该把字符串拆分成小块,还是用正则表达式,然后再用日历函数来获取 'Mar-2010' 的最后一天呢?(获取每个月的第一天很简单,通常都是1,除非我想要这个月的第一个工作日)。
有什么建议吗?提前谢谢!
5 个回答
2
from datetime import datetime, timedelta
def first_day(some_date):
return some_date.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
def next_month(some_date):
return first_day(first_day(some_date) + timedelta(days=31))
def last_day(some_date):
return next_month(some_date) - timedelta(days=1)
# testing:
months = [('Jan-2010', 'Mar-2010'), # your example
('Apr-2009', 'Apr-2009'), # same month, 30 days
('Jan-2008', 'Dec-2008'), # whole year
('Jan-2007', 'Feb-2007')] # february involved
for date1, date2 in months:
print first_day(datetime.strptime(date1, '%b-%Y')),
print '-',
print last_day(datetime.strptime(date2, '%b-%Y'))
这段代码会输出:
2010-01-01 00:00:00 - 2010-03-31 00:00:00
2009-04-01 00:00:00 - 2009-04-30 00:00:00
2008-01-01 00:00:00 - 2008-12-31 00:00:00
2007-01-01 00:00:00 - 2007-02-28 00:00:00
4
我强烈推荐使用 Python 的时间序列模块,你可以在这里下载并了解更多信息:
http://pytseries.sourceforge.net/
你还应该使用 dateutil 这个包来解析日期字符串,相关信息可以在这里找到:
http://labix.org/python-dateutil
然后你可以像这样做:
import datetime
import dateutil.parser
import scikits.timeseries as TS
m1 = TS.Date('M', datetime=dateutil.parser.parse('Jan-2010'))
m2 = TS.Date('M', datetime=dateutil.parser.parse('Mar-2010'))
d1 = m1.asfreq('D', relation='START') # returns a TS.Date object
d2 = m2.asfreq('D', relation='END')
firstDay = d1.datetime
lastDay = d2.datetime
这个解决方案依赖于外部模块,但它们非常强大且写得很好。
6
strptime
可以帮你把字符串转换成日期,省去了你自己去解析的麻烦:
def firstofmonth(MmmYyyy):
return datetime.datetime.strptime(MmmYyyy, '%b-%Y').date()
这比自己去处理分词、正则表达式等要简单得多!
如果你想得到一个月的最后一天,确实可以使用日历模块:
def lastofmonth(MmmYyyy):
first = firstofmonth(MmmYyyy)
_, lastday = calendar.monthrange(first.year, first.month)
return datetime.date(first.year, first.month, lastday)
你几乎可以仅用 datetime 来做到这一点,下面是一个几乎可行的方法:
def lastofmonth(MmmYyyy):
first = firstofmonth(MmmYyyy)
return first.replace(month=first.month+1, day=1
) - datetime.timedelta(days=1)
但是,唉!这个方法在处理十二月时会出问题,而为了处理十二月的特殊情况,代码会变得比用日历模块还要复杂;-)。