我想在python中編寫一個小預算程序。這是我寫的第一個學習python的程序。第一步是根據今天的日期計算直到第一天或第十五天(工資日)爲止的天數。有人能幫我一點嗎?計算時間,直到本月的第1或第15個月python
回答
我不想通過輸入答案來完全破壞你的學習體驗,但是Python庫使得這很容易。查看datetime模塊,特別是date
和timedelta
類。
datetime
模塊中的類將有所幫助。
你只需要檢查是否在本月15號之後。如果是,找到下個月的第一個。如果不是,找到當前月份的第15個。
另一種方法是找到兩者並返回較短的一個 – 2010-04-30 04:56:49
@Carson Myers,顯然是更好的。你需要找到更短的AND正數,否則。具體來說,找到當前月份的第十五個tdelta,如果積極,很好,並且全部完成;否則,請在下個月的第一天返回tdelta。 – Dingle 2010-04-30 19:39:59
是的,你是對的,我正在考慮沿着「找到下一個1和接下來的15個,並返回更接近的一個」的路線,但我想你不能找到接下來的15個,你必須檢查在幾個月內。 – 2010-04-30 20:45:25
有趣的問題,這裏有一個完整的解決方案。我會用函數的定義開始,我已經把這個名爲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的新手,所以我會全力以赴,給你一個使用unittests的例子。
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
運行它。這應該立即失敗,各種錯誤消息,因爲我們還沒有寫好正確的代碼。
經過一段日期時間日期的工作後,我已經制定出: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
運行單元測試,它應該是全金。請注意,在我的測試中,我確定如果我查看發薪日的「下一個」發薪日是什麼,它將返回它自己的一天。將這改爲返回「下一個」發薪日是作爲讀者的練習。
醜陋,沒有文檔字符串,但相當多的比在本月結束while循環timedelta暴力破解打火機...
import datetime
from itertools import cycle
PAYDAYS = (1, 8, 15, 22, 20, 25, 30)
def calculate_days_difference(date_, day=None, next_month=False):
day = day or date_.day
year = date_.year
month = date_.month
if next_month:
if month == 12:
year = year + 1
month = 1
else:
month = month + 1
return (datetime.date(year, month, day) - date_).days
def calculate_days_to_payday(date_, paydays=PAYDAYS):
day = date_.day
if day in paydays:
return 0
if day > max(paydays):
return calculate_days_difference(date_, paydays[0], True)
for payday in cycle(paydays):
if (day > payday):
continue
return calculate_days_difference(date_, payday)
用法:
test_data = (
((2010,04,28), 2),
((2010,04,01), 0),
((2010,04,30), 0),
)
for _input, _output in test_data:
d = datetime.date(*input)
for i in xrange(1000000):
assert calculate_days_to_payday(d) == _output
這將與任何合理的paydays
...排序,並all(1 <= payday <= 28 for payday in paydays)
#否則工人罷工每年二月。
from datetime import date
def calculate_days_to_payday(start_date=None, paydays=(1, 15)):
if start_date is None:
start_date = date.today()
day = start_date.day
for payday in paydays:
if payday >= day:
return payday - day
# next payday is in next month
month = start_date.month + 1
year = start_date.year
if month == 13:
month = 1
year += 1
return (date(year, month, paydays[0]) - start_date).days
if __name__ == "__main__":
tests = (
(1, 12, 0),
(2, 12, 13),
(14, 12, 1),
(15, 12, 0),
(16, 12, 16),
(31, 12, 1),
)
for d, m, expected in tests:
actual = calculate_days_to_payday(date(2009, m, d))
print "%5s" * 5 % (d, m, expected, actual, actual == expected)
- 1. SQL下一年的第15個月
- 2. SSRS參數開始日期本月的前1個月前到本月的第1天
- 3. 計算月數的第一天
- 4. 從週數開始計算日期 - 年份從3月開始 - 第1周= 3月第1周 - PHP
- 5. 從日到月:計算月
- 6. 計算一個月的工作時間
- 7. jQuery datepicker每月的特定日期(即:僅第1次和第15次)
- 8. 獲取當月的第一天-1個月
- 9. 如何在每月的第一天添加1個月至datetimepicker?
- 10. SSRS 2008本月計算本月
- 11. 獲取計數的第六個月,過去六個月FYear
- 12. 使用熊貓計算12月 - 1月 - 2月的平均值
- 13. 本月的第一天
- 14. Paypal CreateRecurringPaymentsProfile第一個月自動結算
- 15. Python中給定月份的第一個月
- 16. 如何獲得當月的時間戳,一個月的第一天,零時
- 17. 如何計算excel中從1月到5月兩個月之間的工作日數?
- 18. 計算Joda時間的月差
- 19. JavaScript直到下個月的第一個分鐘
- 20. 每個月的第一天
- 21. 計算一個月
- 22. 上個月計算
- 23. 計算幾個月
- 24. 「1月第二週」的合理RRULE?
- 25. Excel按季度計算,基於第一個月的日期
- 26. 如何在C#計算出每月的第二個星期五
- 27. 使用.NET計算一個月中的第幾周
- 28. 根據月份的第一天計算出第一個日曆星期六
- 29. 如何查找db2當前月份的第28個月到第27個月的天數
- 30. 日期時間( '四月的第一天')返回相同的日期時間( '五月的第一天')
正如他們在下面所說的,datetime是繼續進行的方式,但這已成爲削減你的牙齒的一個更加複雜的模塊。這並不複雜,因爲它寫得很差,只是公曆和球形地球有很多屬性。 – msw 2010-04-30 06:08:46