在Python中计算距离每月1号或15号的时间
我正在尝试用Python写一个简单的预算程序。这是我写的第一个程序,目的是学习Python。第一步是根据今天的日期计算距离下一个1号或15号(发工资的日子)还有多少天。有人能帮我一下吗?
5 个回答
2
datetime
模块里的类会对你有帮助。
你只需要检查一下现在是不是已经过了这个月的15号。如果过了,就找下个月的1号。如果还没过,就找这个月的15号。
2
我不想直接给你答案,这样会影响你的学习体验,但用Python的库来做这个事情非常简单。你可以看看datetime模块,特别是里面的date
和timedelta
类。
6
这是个有趣的问题,下面是一个完整的解决方案。我会先定义我的函数,我把它放在一个叫做 payday.py
的文件里:
def nexypayday(fromdate=None):
"""
@param fromdate: An instance of datetime.date that is the day to go from. If
not specified, todays date is used.
@return: The first payday on or after the date specified.
"""
接下来我们需要一些测试。这是为了明确我们方法的行为。因为你刚接触python,我会尽量详细,给你一个使用单元测试的例子。
from unittest import TestCase, main
import payday
import datetime
class TestPayday(TestCase):
def test_first_jan(self):
self.assertEqual(payday.nextpayday(datetime.date(2010, 1, 1)),
datetime.date(2010, 1, 1))
def test_second_jan(self):
self.assertEqual(payday.nextpayday(datetime.date(2010, 1, 2)),
datetime.date(2010, 1, 15))
def test_fifteenth_jan(self):
self.assertEqual(payday.nextpayday(datetime.date(2010, 1, 15)),
datetime.date(2010, 1, 15))
def test_thirty_one_jan(self):
self.assertEqual(payday.nextpayday(datetime.date(2010, 1, 31)),
datetime.date(2010, 2, 1))
def test_today(self):
self.assertTrue(payday.nextpayday() >= datetime.date.today())
if __name__ == '__main__':
main()
这是一个可以运行的python模块。你可以把它命名为 test_payday.py
,然后用 python test_payday.py
来运行它。运行后会立即出现各种错误信息,因为我们还没有写好正确的代码。
经过一些对datetime.date的研究,我发现:mydatetime.day
是这个月的日期,mydatetime + datetime.timedelta(days=1)
会创建一个新的 datetime
,表示明天的日期。因此我可以在 payday.py
中写出这个代码。
import datetime
def nextpayday(fromdate=None):
"""
@param fromdate: An instance of datetime.date that is the day to go from. If
not specified, todays date is used.
@return: The first payday on or after the date specified.
"""
if fromdate is None:
fromdate = datetime.date.today()
# while the day of the month isn't 1 or 15, increase the day by 1
while fromdate.day not in (1, 15):
fromdate = fromdate + datetime.timedelta(days=1)
return fromdate
运行单元测试,应该一切正常。注意,在我的测试中,我设置了如果我查看某个发薪日的“下一个”发薪日,它会返回它自己的日期。把这个改成返回“下一个”发薪日的功能留给你自己去练习。