Created
April 5, 2010 00:39
-
-
Save jarodl/355852 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Do common operations on dates""" | |
__author__ = "Jarod Luebbert ([email protected])" | |
__version__ = "$Revision: 0.0.1 $" | |
__date__ = "$Date: 2010/04/01 10:57PM $" | |
from math import ceil | |
class Date: | |
"Stores date information" | |
days_in_month = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) | |
def __init__(self, month, day, year): | |
assert type(month) is int, "month must be an integer" | |
assert type(day) is int, "day must be an integer" | |
assert type(year) is int, "year must be an integer" | |
assert 0 < month < 13, "month out of range (must be 1..12)" | |
assert 0 < day < 32, "day out of range (must be 1..31)" | |
assert year > 0, "year out of range (must be > 0)" | |
self.month = month | |
self.day = day | |
self.year = year | |
def __str__(self): | |
return '%d-%02d-%02d' % (self.year, self.month, self.day) | |
def __eq__(self, other): | |
"Returns true if the date is equal by day, month and year." | |
if isinstance(other, Date): | |
return (self.month == other.month and | |
self.day == other.day and | |
self.year == other.year) | |
else: | |
return NotImplemented | |
def __ne__(self, other): | |
"Returns false if the date differs by day, month or year." | |
result = self.__eq__(other) | |
if result is NotImplemented: | |
return result | |
else: | |
return not result | |
def months_back(self, months_back): | |
"Moves the date back in months" | |
if self.month <= months_back: | |
self.year -= ceil(float(months_back - self.month + 1) / 12) | |
self.month = 12 - abs(self.month - months_back) % 12 | |
else: | |
self.month -= months_back | |
self.update_day() | |
def months_ahead(self, months_ahead): | |
"Moves the date forward in months" | |
if months_ahead >= 12: | |
self.year += ceil(float(months_ahead + self.month) / 12) - 1 | |
self.month = (self.month + months_ahead) % 12 | |
else: | |
self.month += months_ahead | |
self.update_day() | |
def update_day(self): | |
"""Updates the day if it is greater than the number of days | |
the current month has.""" | |
if self.day > self.days_in_month[self.month - 1]: | |
self.day = self.days_in_month[self.month - 1] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from date import Date | |
import unittest | |
class DateBadInput(unittest.TestCase): | |
def testTooLarge(self): | |
"init should fail with large input" | |
self.assertRaises(AssertionError, Date, 1, 32, 2010) | |
self.assertRaises(AssertionError, Date, 13, 1, 2010) | |
def testZero(self): | |
"init should fail with 0 input" | |
self.assertRaises(AssertionError, Date, 0, 1, 2010) | |
def testNonInteger(self): | |
"init should fail with non-integer input" | |
self.assertRaises(AssertionError, Date, "str", 30, 2010) | |
self.assertRaises(AssertionError, Date, 1, "str", 2010) | |
self.assertRaises(AssertionError, Date, 1, 30, "str") | |
def testNegative(self): | |
"init should fail with negative input" | |
self.assertRaises(AssertionError, Date, -1, 1, 2010) | |
self.assertRaises(AssertionError, Date, 1, -1, 2010) | |
self.assertRaises(AssertionError, Date, 1, 1, -2010) | |
class MonthsAgoCheck(unittest.TestCase): | |
def setUp(self): | |
self.date = Date(4, 2, 2010) | |
def testMonthsAgo(self): | |
"Should move back the correct number of months" | |
self.date.months_back(6) | |
self.assertEqual(self.date, Date(10, 2, 2009)) | |
def testBackAYear(self): | |
"Should account for the year changing" | |
self.date.months_back(25) | |
self.assertEqual(self.date, Date(3, 2, 2008)) | |
def testBackDifferentMonth(self): | |
"Should account for different days in certain months" | |
self.date = Date(3, 31, 2010) | |
self.date.months_back(1) | |
self.assertEqual(self.date, Date(2, 28, 2010)) | |
class MonthsForwardCheck(unittest.TestCase): | |
def setUp(self): | |
self.date = Date(4, 2, 2010) | |
def testMonthsForward(self): | |
"Should move forward the correct number of months" | |
self.date.months_ahead(4) | |
self.assertEqual(self.date, Date(8, 2, 2010)) | |
def testForwardAYear(self): | |
"Should account for the year changing" | |
self.date.months_ahead(25) | |
self.assertEqual(self.date, Date(5, 2, 2012)) | |
def testBackDifferentMonth(self): | |
"Should account for different days in certain months" | |
self.date = Date(1, 31, 2010) | |
self.date.months_ahead(1) | |
self.assertEqual(self.date, Date(2, 28, 2010)) | |
class SanityCheck(unittest.TestCase): | |
def setUp(self): | |
self.date = Date(5, 18, 1989) | |
def testForwardAndBack(self): | |
"""Should move the date forward and back the same amount | |
keeping the original date""" | |
self.date.months_ahead(100) | |
self.date.months_back(100) | |
self.assertEqual(self.date, Date(5, 18, 1989)) | |
def testBackAndForward(self): | |
"""Should move the date back and forward the same amount | |
keeping the original date""" | |
self.date.months_back(100) | |
self.date.months_ahead(100) | |
self.assertEqual(self.date, Date(5, 18, 1989)) | |
class OperatorCheck(unittest.TestCase): | |
def setUp(self): | |
self.date = Date(5, 18, 1989) | |
def testShouldBeEqual(self): | |
"Should return true if two objects have the same date" | |
self.assertTrue(self.date == Date(5, 18, 1989)) | |
def testShouldNotBeEqual(self): | |
"Should return false if two objects have a different date" | |
self.assertTrue(self.date != Date(4, 1, 2010)) | |
def testNotImplemented(self): | |
"Should return NotImplemented if the other object is not a Date" | |
self.assertEquals(self.date.__eq__("string"), NotImplemented) | |
if __name__ == "__main__": | |
unittest.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment