将月份对解析为日期时间

时间:2009-08-13 18:38:56

标签: python datetime

假设我有2个字符串'2010年1月'和'2010年3月',我想解析它返回2个日期时间对象:2010年1月1日和2010年3月31日(即最后一天) )。

python中最好的策略是什么?我应该只是将字符串拆分为令牌或使用正则表达式然后使用日历函数来说明“Mar-2010”的月份的最后一天(第一天是微不足道的,在这种情况下它总是1,除非我想要这个月的第一个工作日。)

有什么建议吗?提前谢谢。

5 个答案:

答案 0 :(得分:5)

strptime代表您将字符串解析为日期:

def firstofmonth(MmmYyyy):
  return datetime.datetime.strptime(MmmYyyy, '%b-%Y').date()

要好于使用标记化,正则表达式和& c! - )。

要获取该月最后一天的日期,您确实可以使用日历模块:

def lastofmonth(MmmYyyy):
  first = firstofmonth(MmmYyyy)
  _, lastday = calendar.monthrange(first.year, first.month)
  return datetime.date(first.year, first.month, lastday)

你几乎可以单独使用日期时间来完成它,例如ALMOST工作方法:

def lastofmonth(MmmYyyy):
  first = firstofmonth(MmmYyyy)
  return first.replace(month=first.month+1, day=1
             ) - datetime.timedelta(days=1)

但是,唉!,这打破了12月,特殊情况12月所需的代码使整体方法比日历提供更好; - )。

答案 1 :(得分:3)

我强烈推荐使用python timeseries模块,你可以在这里下载和阅读:

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

这个解决方案依赖于外部模块,但它们非常强大且编写得很好。

答案 2 :(得分: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

答案 3 :(得分:1)

我知道它已经很久没了,但如果有人需要:

from dateutil import rrule
from dateutil import parser
from datetime import datetime

first_day = parser.parse('Jan-2010',default=datetime(1,1,1))
last_day  = rrule.rrule(rrule.MONTHLY,count=1,bymonthday=-1, bysetpos=1,dtstart=parser.parse('Mar-2010'))

答案 4 :(得分:0)

对Alex Martelli的R:

import datetime
def lastofmonthHelper(MmmYyyy): # Takes a date
  return MmmYyyy.replace(year=MmmYyyy.year+(MmmYyyy.month==12), month=MmmYyyy.month%12 + 1, day=1) - datetime.timedelta(days=1)

>>> for month in range(1,13):
...     t = datetime.date(2009,month,1)
...     print t, lastofmonthHelper(t)
...
2009-01-01 2009-01-31
2009-02-01 2009-02-28
2009-03-01 2009-03-31
2009-04-01 2009-04-30
2009-05-01 2009-05-31
2009-06-01 2009-06-30
2009-07-01 2009-07-31
2009-08-01 2009-08-31
2009-09-01 2009-09-30
2009-10-01 2009-10-31
2009-11-01 2009-11-30
2009-12-01 2009-12-31

您不必使用本月的第一天BTW。我会把它放在评论中,但我们都知道如何格式化。随意提升亚历克斯。

如果使用firstofmonth()调用的结果调用,则会得到所需的结果:

>>> lastofmonthHelper(firstofmonth('Apr-2009'))
datetime.date(2009, 4, 30)