Skip to content

Instantly share code, notes, and snippets.

@jarodl
Created April 5, 2010 00:39
Show Gist options
  • Save jarodl/355852 to your computer and use it in GitHub Desktop.
Save jarodl/355852 to your computer and use it in GitHub Desktop.
"""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]
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