2007-08-07

 

Python Cookbook 3.2 查找最近的星期五

需求:

你需要知道最近星期五的日期(或者是今天,如果今天是星期五),然后用特定的格式输出.

讨论:

你可以使用datetime模块来实现这个需求:

import datetime, calendar
lastFriday = datetime.date.today( )
oneday = datetime.timedelta(days=1)
while lastFriday.weekday ( ) != calendar.FRIDAY:
    lastFriday -= oneday
print lastFriday.strftime ('%A, %d-%b-%Y')
# emits, e.g.: Friday, 10-Dec-2004

上面的代码方便的实现了查找最近的星期五,并用特定的格式输出,无论这个周五是不是处于同一月,甚至同一年.在这个例子里面,我们查找最近的星期五.星期五的整数表示是4 ,但是为了避免使用这个"魔幻数字",我们使用Python标准库的calendar模块中的calendar.FRIDAY来表示(当然,我敢确定,它的值也是4).我们设置了一个变量叫做lastFriday,它保存今天的日期,然后让它递减,直到它的weekday值为4.
一旦我们找到了需要的日期,格式化输出就变得异常简单,使用datetime.date的strftime方法就可以了.
另一个更简洁的做法是使用内建的常量datetime.date.resolution来替代datetime.timedelta来表示一天 .

import datetime, calendar
lastFriday = datetime.date.today( )
while lastFriday.weekday( ) != calendar.FRIDAY:
    lastFriday -= datetime.date.resolution
print lastFriday.strftime('%d-%b-%Y')

类属性datetime.date.resolution表示了一天的时间.然而,resolution可能会混淆你,因为它随着不同的datetime模块其值也是不同的.对于date模块,timedelta(day=1),但是对于time和datetime类,它们的timedelta(microseconds=1),你可以进行混合匹配,但容易搞混.使用本节开始的方法,会更通用一些,也不容易搞混.而且,怎么说它也是最Python的写法(那可是官方版本).
一个重要的需要加强的地方是我们不需要使用循环,一次次的减少时间.我们可以一次性得到目标,使用算数计算就OK了:

import datetime, calendar
today = datetime.date.today ( )
targetDay = calendar.FRIDAY
thisDay = today.weekday( )
deltaToTarget = (thisDay - targetDay) % 7
lastFriday = today - datetime.timedelta(days=deltaToTarget)
print lastFriday.strftime('%d-%b-%Y')

要始终追求最清晰的方式,而不是效率.记住Hoare的名言:"在编程中不成熟的优化是罪恶的根源".让我们看看为什么优化是不成熟的.
用最普通的装备在一个4年的老机器上,跑着linux和Python2.4 ,用本节开始的方法,用时18.4毫秒,用最后的方法,用时10.1毫秒.
在你的一生中,并不会总去计算上周5是什么时候,对吧.接下来...(一些证明词).

相关说明:

weekday(...)
    Return the day of the week represented by the date.
    Monday == 0 ... Sunday == 6

strftime(...)
    format -> strftime() style string.

标签:


Comments: 发表评论



<< Home

This page is powered by Blogger. Isn't yours?