将月份年份对解析为日期时间

7 投票
5 回答
4782 浏览
提问于 2025-04-15 13:35

假设我有两个字符串,分别是 '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)

但是,唉!这个方法在处理十二月时会出问题,而为了处理十二月的特殊情况,代码会变得比用日历模块还要复杂;-)。

撰写回答