对Python datetime对象进行按月为单位的增减
Python内置的datetime很好用,但也有一定的局限性。比如我们如果有个datetime对象,然后我想输出这个对象加上13个月后的时间对象怎么办呢?这里面除了要考虑月份的循环周期为12,同时还要考虑每个月的最后一天不尽相同,比如30天和31天的,还有2月的闰年与非闰年等等问题。
当然,我们可以使用其它第三方的Python时间库,但为了这么小个功能去增加一堆安装部署的麻烦实在是有点得不偿失。其实,一小段代码即可。
下面这段代码提供了一个函数用来对一个datetime对象进行增减(date对象参考修改就可以了),具体说明我已经写在了程序的注释里,这里就不多啰嗦了。
import datetime
# input datetime1, and an month offset
# return the result datetime
def datetime_offset_by_month(datetime1, n = 1):
# create a shortcut object for one day
one_day = datetime.timedelta(days = 1)
# first use div and mod to determine year cycle
q,r = divmod(datetime1.month + n, 12)
# create a datetime2
# to be the last day of the target month
datetime2 = datetime.datetime(
datetime1.year + q, r + 1, 1) - one_day
# if input date is the last day of this month
# then the output date should also be the last
# day of the target month, although the day
# may be different.
# for example:
# datetime1 = 8.31
# datetime2 = 9.30
if datetime1.month != (datetime1 + one_day).month:
return datetime2
# if datetime1 day is bigger than last day of
# target month, then, use datetime2
# for example:
# datetime1 = 10.31
# datetime2 = 11.30
if datetime1.day >= datetime2.day:
return datetime2
# then, here, we just replace datetime2's day
# with the same of datetime1, that's ok.
return datetime2.replace(day = datetime1.day)
接下来,写点简单的测试:
# test
d1 = datetime.datetime(2008, 8, 17)
d2 = datetime_offset_by_month(d1, 13)
print '2008-8-17 + 13 month'
print d2
print
d1 = datetime.datetime(2008, 8, 31)
d2 = datetime_offset_by_month(d1, 13)
print '2008-8-31 + 13 month'
print d2
print
d1 = datetime.datetime(2007, 1, 30)
d2 = datetime_offset_by_month(d1, 13)
print '2007-1-30 + 13 month'
print d2
print
输出结果为:
2008-8-17 + 13 month 2009-09-17 00:00:00 2008-8-31 + 13 month 2009-09-30 00:00:00 2007-1-30 + 13 month 2008-02-29 00:00:00

十月 16th, 2008 at 16:47
欢迎你加入bloggermap.org,我们感谢你的支持
十月 16th, 2008 at 17:01
@cosbeta
你们的Idea很不错,祝你们越办越好,就是目前女性会员少了点:)
十月 17th, 2008 at 03:53
哈哈,一本正经的,就你一个人做的,你还来个我们。。。
十月 17th, 2008 at 17:32
@Shawn
哈哈,最近才开始接触博客的世界,蛮好玩的嘛,你们好像都认识,到处逛博客经常能发现认识的人的留言:)
十月 17th, 2008 at 23:08
厄,没看懂,但还是留个言~~
十月 17th, 2008 at 23:12
@JoBru
留言是美德,回复也是,:)去踩踩你的博客~~
十一月 3rd, 2008 at 05:57
我好像来过你的博客了。不过既然来了。给你留点东西吧 (*^__^*) 嘻嘻……
十一月 6th, 2008 at 20:57
生是做网站的人。死是做网站的鬼。我的网站什么时候才有你网站的那么成功啊。羡慕中~~~
十二月 19th, 2008 at 16:33
datatime里面的timedelta可以达到一样的功能。
我在网上找了半天终于找到了,文档看得不仔细呀。。。
十二月 19th, 2008 at 16:35
@halida 嘿嘿,我后来也发现了:)
十二月 19th, 2008 at 17:16
这就是编程界中的 太阳底下无新事
只要是通用的问题都被解决过的
烦的是客制化的玩意。
十二月 19th, 2008 at 17:24
@halida 后来我发现在PHP中更方便,可以直接把 “+ 3 weeks” 这样的字符串转换为 DateTime 对象。话说时间处理,可以写好多东西了,包括不同语言的实现。
十二月 26th, 2008 at 21:48
不错,转帖到了这里:
http://www.fayaa.com/code/view/586/