#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
gaetk2.tools.datetools - formating and parsing of timestamps.
Created as huTools.calendar.formats and huTools.calendar.workdays
by Maximillian Dornseif and Christian Klein on 2007-06-24.
And on workdays.py created by Christian Klein on 2006-11-28.
Copyright (c) 2007, 2010, 2012, 2013, 2018 HUDORA GmbH. MIT licensed.
"""
from __future__ import absolute_import
from __future__ import unicode_literals
import calendar
import datetime
import doctest
import email.utils
import sys
import time
import unittest
import warnings
[docs]def tertial(date):
"""Wandelt ein Date oder Datetime-Objekt in einen Tertial-String"""
ret = date.strftime('%Y-%m')
ret = (
ret[:-2]
+ {
'01': 'A',
'02': 'A',
'03': 'A',
'04': 'A',
'05': 'B',
'06': 'B',
'07': 'B',
'08': 'B',
'09': 'C',
'10': 'C',
'11': 'C',
'12': 'C',
}[ret[-2:]]
)
return ret
[docs]def rfc3339_date(date=None):
"""Formates a datetime object according to RfC 3339."""
date = date or datetime.datetime.now()
return date.strftime('%Y-%m-%dT%H:%M:%SZ')
[docs]def rfc3339_date_parse(date):
"""Parses an RfC 3339 timestamp into a datetime object."""
return datetime.datetime.strptime(date, '%Y-%m-%dT%H:%M:%SZ')
[docs]def convert_to_date(date):
"""Converts argument into a date object.
Assumes argument to be a RfC 3339 coded date or a date(time) object.
"""
if hasattr(date, 'date') and callable(date.date):
# e.g. datetime objects
return date.date()
elif isinstance(date, datetime.date):
return date
elif not date:
return None
elif isinstance(date, basestring):
date = date[:10] # strip time
try:
return datetime.datetime.strptime(date, '%Y-%m-%d').date()
except ValueError:
try:
date = date[:8] # strip time
return datetime.datetime.strptime(date, '%Y%m%d').date()
except ValueError:
pass # Error will be raised later on
raise ValueError('Unknown date value {!r} ({})'.format(date, type(date)))
[docs]def convert_to_datetime(date):
"""Converts argument into a datetime object.
Assumes argument to be a RfC 3339 coded date or a date(time) object.
"""
if isinstance(date, datetime.datetime):
return date
elif isinstance(
date, datetime.date
): # order mattes! datetime is a subclass of date
return datetime.datetime(date.year, date.month, date.day)
elif isinstance(date, basestring):
if len(date) < 11:
return convert_to_datetime(convert_to_date(date))
else:
# remove Timezone
if date.endswith(' +0000'):
date = date.rstrip(' +0')
date = date.rstrip('Z')
# handle milliseconds
ms = 0
if '.' in date:
date, ms = date.split('.')
if len(date.split(':')) > 1 and len(date.split(':')) < 3:
date = date + ':00' # append seconds
try:
ret = datetime.datetime.strptime(date, '%Y-%m-%dT%H:%M:%S')
except ValueError:
try:
ret = datetime.datetime.strptime(date, '%Y-%m-%d %H:%M:%S')
except ValueError:
ret = datetime.datetime.strptime(date, '%Y%m%dT%H%M%S')
if ms:
return datetime.datetime(
ret.year,
ret.month,
ret.day,
ret.hour,
ret.minute,
ret.second,
int(ms),
)
return ret
elif not date:
return None
raise ValueError('Unknown value {!r} ({})'.format(date, type(date)))
[docs]def rfc2616_date(date=None):
"""Formates a datetime object according to RfC 2616.
RfC 2616 is a subset of RFC 1123 date.
Weekday and month names for HTTP date/time formatting; always English!
"""
date = date or datetime.datetime.now()
return email.utils.formatdate(time.mktime(date.timetuple()), usegmt=True)
[docs]def rfc2616_date_parse(data):
"""Parses an RfC 2616/2822 timestapm into a datetime object."""
return datetime.datetime.fromtimestamp(
email.utils.mktime_tz(email.utils.parsedate_tz(data))
)
[docs]def date_trunc(trtype, timestamp):
"""
Truncate date or datetime object. Truncated object of the given type.
This function is inspired by date_trunc from PostgreSQL, see
http://www.postgresql.org/docs/8.1/static/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
Supported types are year, quarter, month, week, day, hour, minute, second.
>>> date_trunc('week', datetime.datetime(1974, 8, 21))
datetime.datetime(1974, 8, 19, 0, 0)
>>> date_trunc('week', datetime.date(1973, 8, 8))
datetime.date(1973, 8, 6)
"""
if isinstance(timestamp, basestring):
# we are called with the old calling convention
warnings.warn(
'`date_trunc` should be called with a date/datetime object as the second parameter',
DeprecationWarning,
stacklevel=2,
)
timestamp, trtype = trtype, timestamp
tmp = timestamp.timetuple()
if trtype == 'year':
ret = datetime.datetime(tmp.tm_year, 1, 1)
elif trtype == 'tertial':
ret = datetime.datetime(tmp.tm_year, 1 + (get_tertial(timestamp) - 1) * 4, 1)
elif trtype == 'quarter':
ret = datetime.datetime(tmp.tm_year, 3 * (get_quarter(timestamp) - 1) + 1, 1)
elif trtype == 'month':
ret = datetime.datetime(tmp.tm_year, tmp.tm_mon, 1)
elif trtype == 'week':
firstday = timestamp - datetime.timedelta(days=tmp.tm_wday)
ret = datetime.datetime.combine(firstday, datetime.time(0))
elif trtype == 'day':
ret = datetime.datetime(tmp.tm_year, tmp.tm_mon, tmp.tm_mday)
elif trtype == 'hour':
ret = datetime.datetime(tmp.tm_year, tmp.tm_mon, tmp.tm_mday, tmp.tm_hour)
elif trtype == 'minute':
ret = datetime.datetime(
tmp.tm_year, tmp.tm_mon, tmp.tm_mday, tmp.tm_hour, tmp.tm_min
)
elif trtype == 'second':
ret = datetime.datetime(
tmp.tm_year, tmp.tm_mon, tmp.tm_mday, tmp.tm_hour, tmp.tm_min, tmp.tm_sec
)
else:
raise ValueError('Unknown truncation type %s' % trtype)
# if we where given a datetime object return it, else assume a date object and cast our return
# value to that
if isinstance(timestamp, datetime.datetime):
return ret
return ret.date()
[docs]def get_tertial(date):
"""
Calculates the tertial
>>> get_tertial(datetime.date(2015, 1, 9))
1
>>> get_tertial(datetime.datetime(2015, 2, 19))
1
>>> get_tertial(datetime.date(2015, 3, 9))
1
>>> get_tertial(datetime.datetime(2015, 4, 20))
1
>>> get_tertial(datetime.datetime(2015, 5, 4))
2
>>> get_tertial(datetime.datetime(2015, 6, 11))
2
>>> get_tertial(datetime.datetime(2015, 7, 22))
2
>>> get_tertial(datetime.date(2015, 8, 3))
2
>>> get_tertial(datetime.date(2015, 9, 23))
3
>>> get_tertial(datetime.datetime(2015, 10, 24))
3
>>> get_tertial(datetime.date(2015, 11, 11))
3
>>> get_tertial(datetime.datetime(2015, 12, 6))
3
"""
return (date.month - 1) / 4 + 1
[docs]def get_quarter(date):
"""
Calculates the quarter
>>> get_quarter(datetime.date(2015, 1, 9))
1
>>> get_quarter(datetime.datetime(2015, 2, 19))
1
>>> get_quarter(datetime.date(2015, 3, 9))
1
>>> get_quarter(datetime.datetime(2015, 4, 20))
2
>>> get_quarter(datetime.datetime(2015, 5, 4))
2
>>> get_quarter(datetime.datetime(2015, 6, 11))
2
>>> get_quarter(datetime.datetime(2015, 7, 22))
3
>>> get_quarter(datetime.date(2015, 8, 3))
3
>>> get_quarter(datetime.date(2015, 9, 23))
3
>>> get_quarter(datetime.datetime(2015, 10, 24))
4
>>> get_quarter(datetime.date(2015, 11, 11))
4
>>> get_quarter(datetime.datetime(2015, 12, 6))
4
"""
return (date.month - 1) / 3 + 1
[docs]def get_yearspan(date):
"""Gibt den ersten und letzten Tag des Jahres zurück in dem `date` liegt
>>> get_yearspan(datetime.date(1980, 5, 4))
(datetime.date(1980, 1, 1), datetime.date(1980, 12, 31))
>>> get_yearspan(datetime.date(1986, 3, 11))
(datetime.date(1986, 1, 1), datetime.date(1986, 12, 31))
"""
startdate = date_trunc('year', date)
enddate = type(startdate)(startdate.year, 12, 31)
return startdate, enddate
[docs]def get_tertialspan(date):
"""Gibt den ersten und den letzten Tag des Tertials zurück in dem `date` liegt
>>> get_tertialspan(datetime.date(1978, 9, 23))
(datetime.date(1978, 9, 1), datetime.date(1978, 12, 31))
"""
startdate = date_trunc('tertial', date)
enddate = date_trunc(
'tertial', startdate + datetime.timedelta(days=130)
) - datetime.timedelta(days=1)
return startdate, enddate
[docs]def get_quarterspan(date):
"""Gibt den ersten und den letzten Tag des Quartals zurück in dem `date` liegt
>>> get_quarterspan(datetime.date(1978, 6, 12))
(datetime.date(1978, 4, 1), datetime.date(1978, 6, 30))
"""
startdate = date_trunc('quarter', date)
# The date 100 days after the beginning of a quarter is always right inside the next quarter
enddate = date_trunc(
'quarter', startdate + datetime.timedelta(days=100)
) - datetime.timedelta(days=1)
return startdate, enddate
[docs]def get_monthspan(date):
"""Gibt den ersten und letzten Tag des Monats zurück in dem `date` liegt
>>> get_monthspan(datetime.date(1980, 5, 4))
(datetime.date(1980, 5, 1), datetime.date(1980, 5, 31))
"""
startdate = date_trunc('month', date)
_, days = calendar.monthrange(startdate.year, startdate.month)
enddate = type(startdate)(startdate.year, startdate.month, days)
return startdate, enddate
[docs]def get_weekspan(date):
"""Gibt den ersten und den letzten Tag der Woche, in der `date` liegt, zurück.
Dabei ist Montag der erste Tag der woche und Sonntag der letzte.
>>> get_weekspan(datetime.date(2011, 3, 23))
(datetime.date(2011, 3, 21), datetime.date(2011, 3, 27))
"""
startdate = date_trunc('week', date)
enddate = startdate + datetime.timedelta(days=6)
return startdate, enddate
[docs]def get_timespan(period, date):
"""
Get given timespan for date
Convenience function as a wrapper for the other get_*span functions
"""
if period == 'year':
return get_yearspan(date)
elif period == 'tertial':
return get_tertialspan(date)
elif period == 'quarter':
get_quarterspan(date)
elif period == 'month':
return get_monthspan(date)
elif period == 'week':
return get_weekspan(date)
elif period == 'day':
return date, date
else:
raise ValueError('Unknown truncation type %s' % period)
[docs]def tertial_add(date, tertials):
"""Add number of tertials to date.
>>> date = datetime.date(1982, 11, 7)
>>> tertial_add(date, -1)
datetime.date(1982, 5, 1)
>>> tertial_add(date, 0)
datetime.date(1982, 9, 1)
>>> tertial_add(date, 1)
datetime.date(1983, 1, 1)
>>> tertial_add(date, 2)
datetime.date(1983, 5, 1)
>>> tertial_add(date, 3)
datetime.date(1983, 9, 1)
>>> tertial_add(date, 4)
datetime.date(1984, 1, 1)
>>> date = datetime.datetime(1982, 11, 7)
>>> tertial_add(date, 4)
datetime.datetime(1984, 1, 1)
"""
date = date_trunc('tertial', date)
month = date.month + tertials * 4
return date.replace(year=date.year + month // 12, month=month % 12)
[docs]def month_add(date, months):
"""Add number of months to date.
>>> import datetime
>>> date = datetime.date(1986, 3, 9)
>>> month_add(date, -12)
datetime.date(1985, 3, 9)
>>> month_add(date, -1)
datetime.date(1986, 2, 9)
>>> month_add(date, 0)
datetime.date(1986, 3, 9)
>>> month_add(date, 3)
>>> date = datetime.datetime(1986, 3, 9)
>>> month_add(date, 12)
datetime.datetime(1987, 3, 9)
"""
year, month = divmod(date.year * 12 + date.month + months, 12)
return date.replace(year=year, month=month)
[docs]def year_add(date, years):
"""Add number of years to date.
>>> import datetime
>>> year_add(datetime.datetime(2016, 2, 29), 1)
datetime.date(2017, 2, 28)
>>> year_add(datetime.date(2016, 2, 29), 1)
datetime.date(2017, 2, 28)
>>> year_add(datetime.date(2015, 2, 28), 1)
datetime.date(2016, 2, 28)
>>> year_add(datetime.date(2017, 2, 28, -1)
datetime.date(2016, 2, 28)
>>> year_add(datetime.datetime(2016, 2, 29), -1)
datetime.datetime(2015, 2, 28)
"""
if date.day == 29 and date.month == 2 and not calendar.isleap(date.year + years):
return date.replace(day=28, year=date.year + years)
return date.replace(year=date.year + years)
STATIC_GERMAN_HOLIDAYS = (
(1, 1), # Neujahr
(5, 1), # Tag der Arbeit
(10, 3), # Tag der deutschen Einheit
(11, 1), # Allerheiligen
(12, 25), # Erster Weihnachtstag
(12, 26), # Zweiter Weihnachtstag
)
[docs]def add_to_day(day, offset):
"""Returns the date n days before or after day."""
return day + datetime.timedelta(days=offset)
[docs]def easter(year):
"""Returns the day of Easter sunday for 'year'.
This function only works betweeen 1900 and 2099
"""
h = (24 + 19 * (year % 19)) % 30
i = h - (h / 28)
j = (year + (year / 4) + i - 13) % 7
l = i - j
easter_month = 3 + ((l + 40) / 44)
easter_day = l + 28 - 31 * (easter_month / 4)
return (easter_month, easter_day)
[docs]def holidays_german(start, end):
"""Returns a list of dates between start and end that are holidays."""
hdays = []
# Berechne alle Feiertage in den Jahren a bis b.
# Falls a == b werden auch die Feiertage des nächsten
# Jahres mitberechnet, aber die Liste muss sowieso
# nochmal gefiltert werden.
for year in range(start.year, end.year + 1):
for month, day in STATIC_GERMAN_HOLIDAYS:
hdays.append(datetime.date(year, month, day))
hdays += easter_related_holidays(year)
return hdays
[docs]def workdays(start, end):
"""Calculates the number of working days (Mo-Fr) between two given dates.
Whereas the workdays are calculated siilar to Python slice notation: [start : end[
Example:
>>> workdays(datetime.date(2007, 1, 26), datetime.date(2007, 1, 27)) # Fr - Sa
1
>>> workdays(datetime.date(2007, 1, 28), datetime.date(2007, 1, 29)) # Su - Mo
0
"""
start = convert_to_date(start)
end = convert_to_date(end)
if start > end:
return -1 * _workdays(end, start)
else:
return _workdays(start, end)
def _workdays(start, end):
'Helper for `workdays()`.'
if start > end:
raise ValueError(
"can't handle negative timespan! {!r} > {!r}".format(start, end)
)
# Wenn Anfangstag auf Wochenende liegt, addiere Tage bis Montag
while start.isoweekday() > 5:
start = add_to_day(start, 1)
# Wenn Endtag auf Wochenende liegt, substrahiere Tage bis Freitag
while end.isoweekday() > 5:
end = add_to_day(end, 1)
days = (end - start).days
# Count weekends:
# if weekday start < weekday end: n / 7
# if weekday start > weekday end: (n / 7) + 1
number_of_weekends = days / 7
if start.isoweekday() > end.isoweekday():
number_of_weekends += 1
days = days - 2 * number_of_weekends
if days < 0:
raise RuntimeError(
'{!r} days difference {!r}|{!r}|{!r}'.format(
days, start, end, number_of_weekends
)
)
return days
[docs]def workdays_german(start, end):
"""Calculates the number of working days between two given dates while considering german holidays."""
if isinstance(start, datetime.datetime):
start = start.date()
if isinstance(end, datetime.datetime):
end = end.date()
days = workdays(start, end)
# Deduct Holidays (but only the ones not on weekends)
holid = [
x
for x in holidays_german(start, end)
if (x >= start) and (x < end) and (x.isoweekday() < 6)
]
return days - len(holid)
[docs]def is_workday_german(day):
"""Checks if a day is a workday in germany (NRW).
>>> is_workday_german(datetime.date(2007, 1, 1))
False
>>> is_workday_german(datetime.date(2007, 1, 2))
True
"""
if day.isoweekday() > 5:
return False # weekend
if isinstance(day, datetime.datetime):
day = day.date()
return day not in holidays_german(day, day)
[docs]def next_workday_german(startday):
"""Returns the next workday after startday.
>>> next_workday_german(datetime.date(2006, 12, 29))
datetime.date(2007, 1, 2)
"""
next_day = add_to_day(startday, 1)
while not is_workday_german(next_day):
next_day = add_to_day(next_day, 1)
return next_day
[docs]def previous_workday_german(startday):
"""Returns the workday before startday.
>>> previous_workday_german(datetime.date(2007, 1, 2))
datetime.date(2006, 12, 29)
"""
prev_day = add_to_day(startday, -1)
while not is_workday_german(prev_day):
prev_day = add_to_day(prev_day, -1)
return prev_day
[docs]def add_workdays_german(startday, count):
"""Adds <count> workdays to <startday>."""
day = startday
while count > 0:
day = next_workday_german(day)
count -= 1
while count < 0:
day = previous_workday_german(day)
count += 1
return day
class _FormatsTests(unittest.TestCase):
def test_rfc3339_date(self):
"""Test basic rfc3339_date output."""
self.assertEqual(
rfc3339_date(datetime.datetime(2007, 2, 3, 4, 5, 6)), '2007-02-03T04:05:06Z'
)
def test_rfc3339_date_parse(self):
"""Test basic rfc3339_date_parse output."""
self.assertEqual(
rfc3339_date_parse('2007-02-03T04:05:06Z'),
datetime.datetime(2007, 2, 3, 4, 5, 6),
)
def test_rfc2616_date(self):
"""Test basic rfc2616_date output."""
self.assertEqual(
rfc2616_date(datetime.datetime(2007, 2, 3, 4, 5, 6)),
'Sat, 03 Feb 2007 03:05:06 GMT',
)
def test_rfc2616_date_parse(self):
"""Test basic rfc2616_date_parse output."""
self.assertEqual(
rfc2616_date_parse('Sat, 03 Feb 2007 03:05:06 GMT'),
datetime.datetime(2007, 2, 3, 4, 5, 6),
)
def test_convert_to_datetime(self):
"""Test convert_to_datetime() and convert_to_date() functionality"""
self.assertEqual(
convert_to_datetime(datetime.date(2007, 2, 3)),
datetime.datetime(2007, 2, 3, 0, 0),
)
self.assertEqual(
convert_to_datetime(datetime.datetime(2007, 2, 3, 13, 14, 15, 16)),
datetime.datetime(2007, 2, 3, 13, 14, 15, 16),
)
self.assertEqual(
convert_to_datetime('2007-02-03'), datetime.datetime(2007, 2, 3, 0, 0)
)
self.assertEqual(
convert_to_datetime('2007-2-3'), datetime.datetime(2007, 2, 3, 0, 0)
)
self.assertEqual(
convert_to_datetime('20070203'), datetime.datetime(2007, 2, 3, 0, 0)
)
self.assertEqual(
convert_to_datetime('20070203T131415'),
datetime.datetime(2007, 2, 3, 13, 14, 15),
)
self.assertEqual(
convert_to_datetime('2007-02-03T13:14:15'),
datetime.datetime(2007, 2, 3, 13, 14, 15),
)
self.assertEqual(
convert_to_datetime('2007-02-03T13:14:15.16'),
datetime.datetime(2007, 2, 3, 13, 14, 15, 16),
)
self.assertEqual(
convert_to_datetime('2007-02-03 13:14:15'),
datetime.datetime(2007, 2, 3, 13, 14, 15),
)
self.assertEqual(
convert_to_datetime('2007-02-03 13:14:15.16'),
datetime.datetime(2007, 2, 3, 13, 14, 15, 16),
)
self.assertEqual(
convert_to_datetime('2013-09-03 21:39:09 +0000'),
datetime.datetime(2013, 9, 3, 21, 39, 9),
)
self.assertEqual(
convert_to_datetime('2013-12-03 13:14'),
datetime.datetime(2013, 12, 3, 13, 14, 0, 0),
)
class _WeekspanTestCase(unittest.TestCase):
"""Unittests for get_weekspan"""
def test_monday(self):
"""get_weekspan for a monday"""
date = datetime.date(1981, 5, 4)
self.assertEqual(date.isoweekday(), 1)
start_date, end_date = get_weekspan(date)
self.assertEqual(start_date.isoweekday(), 1)
self.assertEqual(end_date.isoweekday(), 7)
self.assertTrue(
start_date.toordinal() <= date.toordinal() <= end_date.toordinal()
)
def test_tuesday(self):
"""get_weekspan for a tuesday"""
date = datetime.date(1982, 5, 4)
self.assertEqual(date.isoweekday(), 2)
start_date, end_date = get_weekspan(date)
self.assertEqual(start_date.isoweekday(), 1)
self.assertEqual(end_date.isoweekday(), 7)
self.assertTrue(
start_date.toordinal() <= date.toordinal() <= end_date.toordinal()
)
def test_wednesday(self):
"""get_weekspan for a wednesday"""
date = datetime.date(1988, 5, 4)
self.assertEqual(date.isoweekday(), 3)
start_date, end_date = get_weekspan(date)
self.assertEqual(start_date.isoweekday(), 1)
self.assertEqual(end_date.isoweekday(), 7)
self.assertTrue(
start_date.toordinal() <= date.toordinal() <= end_date.toordinal()
)
def test_thursday(self):
"""get_weekspan for a thursday"""
date = datetime.date(1989, 5, 4)
self.assertEqual(date.isoweekday(), 4)
start_date, end_date = get_weekspan(date)
self.assertEqual(start_date.isoweekday(), 1)
self.assertEqual(end_date.isoweekday(), 7)
self.assertTrue(
start_date.toordinal() <= date.toordinal() <= end_date.toordinal()
)
def test_friday(self):
"""get_weekspan for a friday"""
date = datetime.date(1984, 5, 4)
self.assertEqual(date.isoweekday(), 5)
start_date, end_date = get_weekspan(date)
self.assertEqual(start_date.isoweekday(), 1)
self.assertEqual(end_date.isoweekday(), 7)
self.assertTrue(
start_date.toordinal() <= date.toordinal() <= end_date.toordinal()
)
def test_saturday(self):
"""get_weekspan for a saturday"""
date = datetime.date(1985, 5, 4)
self.assertEqual(date.isoweekday(), 6)
start_date, end_date = get_weekspan(date)
self.assertEqual(start_date.isoweekday(), 1)
self.assertEqual(end_date.isoweekday(), 7)
self.assertTrue(
start_date.toordinal() <= date.toordinal() <= end_date.toordinal()
)
def test_sunday(self):
"""get_weekspan for a sunday"""
date = datetime.date(1980, 5, 4)
self.assertEqual(date.isoweekday(), 7)
start_date, end_date = get_weekspan(date)
self.assertEqual(start_date.isoweekday(), 1)
self.assertEqual(end_date.isoweekday(), 7)
self.assertTrue(
start_date.toordinal() <= date.toordinal() <= end_date.toordinal()
)
class _MonthSpanTestCase(unittest.TestCase):
"""Unittests for get_monthspan"""
def test_january(self):
date = datetime.date(1980, 1, 1)
start_date, end_date = get_monthspan(date)
self.assertTrue(isinstance(start_date, datetime.date))
self.assertTrue(isinstance(end_date, datetime.date))
self.assertEqual(start_date, datetime.date(1980, 1, 1))
self.assertEqual(end_date, datetime.date(1980, 1, 31))
date = datetime.datetime(1980, 1, 31)
start_date, end_date = get_monthspan(date)
self.assertTrue(isinstance(start_date, datetime.datetime))
self.assertTrue(isinstance(end_date, datetime.datetime))
self.assertEqual(start_date, datetime.datetime(1980, 1, 1))
self.assertEqual(end_date, datetime.datetime(1980, 1, 31))
def test_february(self):
date = datetime.date(1945, 2, 19)
start_date, end_date = get_monthspan(date)
self.assertTrue(isinstance(start_date, datetime.date))
self.assertTrue(isinstance(end_date, datetime.date))
self.assertEqual(start_date, datetime.date(1945, 2, 1))
self.assertEqual(end_date, datetime.date(1945, 2, 28))
date = datetime.datetime(1945, 2, 1)
start_date, end_date = get_monthspan(date)
self.assertTrue(isinstance(start_date, datetime.datetime))
self.assertTrue(isinstance(end_date, datetime.datetime))
self.assertEqual(start_date, datetime.datetime(1945, 2, 1))
self.assertEqual(end_date, datetime.datetime(1945, 2, 28))
def test_february_leap(self):
date = datetime.date(1980, 2, 19)
start_date, end_date = get_monthspan(date)
self.assertTrue(isinstance(start_date, datetime.date))
self.assertTrue(isinstance(end_date, datetime.date))
self.assertEqual(start_date, datetime.date(1980, 2, 1))
self.assertEqual(end_date, datetime.date(1980, 2, 29))
date = datetime.datetime(1980, 2, 19)
start_date, end_date = get_monthspan(date)
self.assertTrue(isinstance(start_date, datetime.datetime))
self.assertTrue(isinstance(end_date, datetime.datetime))
self.assertEqual(start_date, datetime.datetime(1980, 2, 1))
self.assertEqual(end_date, datetime.datetime(1980, 2, 29))
def test_june(self):
date = datetime.date(1978, 6, 12)
start_date, end_date = get_monthspan(date)
self.assertTrue(isinstance(start_date, datetime.date))
self.assertTrue(isinstance(end_date, datetime.date))
self.assertEqual(start_date, datetime.date(1978, 6, 1))
self.assertEqual(end_date, datetime.date(1978, 6, 30))
date = datetime.datetime(1978, 6, 12)
start_date, end_date = get_monthspan(date)
self.assertTrue(isinstance(start_date, datetime.datetime))
self.assertTrue(isinstance(end_date, datetime.datetime))
self.assertEqual(start_date, datetime.datetime(1978, 6, 1))
self.assertEqual(end_date, datetime.datetime(1978, 6, 30))
class _QuarterspanTestCase(unittest.TestCase):
"""Unittests for get_quarterspan"""
def test_first(self):
"""Tests for first quarter of a year"""
start_date, end_date = get_quarterspan(datetime.date(1980, 1, 1))
self.assertTrue(start_date < end_date)
self.assertEqual(start_date, datetime.date(1980, 1, 1))
self.assertEqual(end_date, datetime.date(1980, 3, 31))
start_date, end_date = get_quarterspan(datetime.date(1980, 2, 29))
self.assertTrue(start_date < end_date)
self.assertEqual(start_date, datetime.date(1980, 1, 1))
self.assertEqual(end_date, datetime.date(1980, 3, 31))
start_date, end_date = get_quarterspan(datetime.date(1980, 3, 31))
self.assertTrue(start_date < end_date)
self.assertEqual(start_date, datetime.date(1980, 1, 1))
self.assertEqual(end_date, datetime.date(1980, 3, 31))
def test_second(self):
"""Tests for second quarter of a year"""
start_date, end_date = get_quarterspan(datetime.date(1980, 4, 1))
self.assertTrue(start_date < end_date)
self.assertEqual(start_date, datetime.date(1980, 4, 1))
self.assertEqual(end_date, datetime.date(1980, 6, 30))
start_date, end_date = get_quarterspan(datetime.date(1980, 5, 4))
self.assertTrue(start_date < end_date)
self.assertEqual(start_date, datetime.date(1980, 4, 1))
self.assertEqual(end_date, datetime.date(1980, 6, 30))
start_date, end_date = get_quarterspan(datetime.date(1980, 6, 30))
self.assertTrue(start_date < end_date)
self.assertEqual(start_date, datetime.date(1980, 4, 1))
self.assertEqual(end_date, datetime.date(1980, 6, 30))
def test_third(self):
"""Tests for third quarter of a year"""
start_date, end_date = get_quarterspan(datetime.date(1980, 7, 1))
self.assertTrue(start_date < end_date)
self.assertEqual(start_date, datetime.date(1980, 7, 1))
self.assertEqual(end_date, datetime.date(1980, 9, 30))
start_date, end_date = get_quarterspan(datetime.date(1980, 8, 4))
self.assertTrue(start_date < end_date)
self.assertEqual(start_date, datetime.date(1980, 7, 1))
self.assertEqual(end_date, datetime.date(1980, 9, 30))
start_date, end_date = get_quarterspan(datetime.date(1980, 9, 30))
self.assertTrue(start_date < end_date)
self.assertEqual(start_date, datetime.date(1980, 7, 1))
self.assertEqual(end_date, datetime.date(1980, 9, 30))
def test_fourth(self):
"""Tests the fourth quarter of a year"""
start_date, end_date = get_quarterspan(datetime.date(1980, 10, 1))
self.assertTrue(start_date < end_date)
self.assertEqual(start_date, datetime.date(1980, 10, 1))
self.assertEqual(end_date, datetime.date(1980, 12, 31))
start_date, end_date = get_quarterspan(datetime.date(1980, 10, 1))
self.assertTrue(start_date < end_date)
self.assertEqual(start_date, datetime.date(1980, 10, 1))
self.assertEqual(end_date, datetime.date(1980, 12, 31))
start_date, end_date = get_quarterspan(datetime.date(1980, 12, 31))
self.assertTrue(start_date < end_date)
self.assertEqual(start_date, datetime.date(1980, 10, 1))
self.assertEqual(end_date, datetime.date(1980, 12, 31))
def test_all(self):
"""Tests the whole year"""
# year = 1980 #unused
date = datetime.date(1980, 1, 1)
while date < datetime.date(1981, 1, 1):
if date.month <= 3:
mindate, maxdate = datetime.date(1980, 1, 1), datetime.date(1980, 3, 31)
elif date.month <= 6:
mindate, maxdate = datetime.date(1980, 4, 1), datetime.date(1980, 6, 30)
elif date.month <= 9:
mindate, maxdate = datetime.date(1980, 7, 1), datetime.date(1980, 9, 30)
else:
mindate, maxdate = (
datetime.date(1980, 10, 1),
datetime.date(1980, 12, 31),
)
startdate, enddate = get_quarterspan(date)
self.assertTrue(startdate >= mindate)
self.assertTrue(startdate <= maxdate)
self.assertTrue(enddate >= mindate)
self.assertTrue(enddate <= maxdate)
date += datetime.timedelta(days=1)
class _TertialspanTestCase(unittest.TestCase):
"""Unittests for get_tertialspan"""
def test_all(self):
"""Tests the whole year"""
date = datetime.date(1980, 1, 1)
while date < datetime.date(1981, 1, 1):
if date.month <= 4:
mindate, maxdate = datetime.date(1980, 1, 1), datetime.date(1980, 4, 30)
elif date.month <= 8:
mindate, maxdate = datetime.date(1980, 5, 1), datetime.date(1980, 8, 31)
else:
mindate, maxdate = (
datetime.date(1980, 9, 1),
datetime.date(1980, 12, 31),
)
startdate, enddate = get_tertialspan(date)
self.assertTrue(startdate >= mindate)
self.assertTrue(startdate <= maxdate)
self.assertTrue(enddate >= mindate)
self.assertTrue(enddate <= maxdate)
date += datetime.timedelta(days=1)
class _WorkdayTests(unittest.TestCase):
"""Testcases for workdays module.
Calendar hint::
November 2006 December 2006 January 2007
S M Tu W Th F S S M Tu W Th F S S M Tu W Th F S
1 2 3 4 1 2 1 2 3 4 5 6
5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13
12 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20
19 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27
26 27 28 29 30 24 25 26 27 28 29 30 28 29 30 31
31
"""
def test_workdays(self):
"""Simple minded tests for workdays()."""
date = datetime.date
self.assertEqual(0, workdays(date(2007, 1, 25), date(2007, 1, 25))) # Th - Th
self.assertEqual(1, workdays(date(2007, 1, 25), date(2007, 1, 26))) # Th - Fr
self.assertEqual(2, workdays(date(2007, 1, 25), date(2007, 1, 27))) # Th - Sa
self.assertEqual(1, workdays(date(2007, 1, 26), date(2007, 1, 27))) # Fr - Sa
self.assertEqual(1, workdays(date(2007, 1, 26), date(2007, 1, 28))) # Fr - Su
self.assertEqual(1, workdays(date(2007, 1, 26), date(2007, 1, 29))) # Fr - Mo
self.assertEqual(0, workdays(date(2007, 1, 28), date(2007, 1, 29))) # Su - Mo
self.assertEqual(2, workdays(date(2007, 1, 26), date(2007, 1, 30))) # Fr - Tu
self.assertEqual(1, workdays(date(2007, 1, 28), date(2007, 1, 30))) # Su - Tu
self.assertEqual(0, workdays(date(2007, 1, 26), date(2007, 1, 26))) # Fr - Fr
self.assertEqual(1, workdays(date(2007, 1, 26), date(2007, 1, 27))) # Fr - Sa
self.assertEqual(1, workdays(date(2007, 1, 26), date(2007, 1, 28))) # Fr - Su
self.assertEqual(0, workdays(date(2007, 1, 27), date(2007, 1, 28))) # Sa - So
self.assertEqual(0, workdays(date(2007, 1, 27), date(2007, 1, 29))) # Sa - Mo
self.assertEqual(1, workdays(date(2007, 1, 27), date(2007, 1, 30))) # Fr - Tu
self.assertEqual(0, workdays(date(2006, 11, 29), date(2006, 11, 29))) # We - We
self.assertEqual(1, workdays(date(2006, 11, 29), date(2006, 11, 30))) # We - Th
self.assertEqual(1, workdays(date(2006, 11, 30), date(2006, 12, 1))) # Th - Fr
self.assertEqual(5, workdays(date(2006, 12, 12), date(2006, 12, 19))) # Tu - Tu
self.assertEqual(0, workdays(date(2006, 11, 20), date(2006, 11, 20)))
self.assertEqual(1, workdays(date(2006, 11, 20), date(2006, 11, 21)))
self.assertEqual(4, workdays(date(2006, 11, 20), date(2006, 11, 24)))
self.assertEqual(5, workdays(date(2006, 11, 20), date(2006, 11, 25))) # Mo - Sa
self.assertEqual(5, workdays(date(2006, 11, 20), date(2006, 11, 26))) # Mo - Su
self.assertEqual(5, workdays(date(2006, 11, 20), date(2006, 11, 27)))
self.assertEqual(5, workdays(date(2006, 12, 25), date(2007, 1, 1)))
self.assertEqual(6, workdays(date(2006, 12, 8), date(2006, 12, 18)))
self.assertEqual(5, workdays(date(2006, 12, 9), date(2006, 12, 18)))
self.assertEqual(0, workdays(date(2006, 12, 17), date(2006, 12, 18)))
self.assertEqual(1, workdays(date(2006, 12, 17), date(2006, 12, 19)))
self.assertEqual(4, workdays(date(2006, 12, 17), date(2006, 12, 22)))
self.assertEqual(5, workdays(date(2006, 12, 17), date(2006, 12, 23))) # Su - Sa
self.assertEqual(5, workdays(date(2006, 12, 17), date(2006, 12, 24))) # Su - Su
self.assertEqual(5, workdays(date(2006, 12, 17), date(2006, 12, 25)))
self.assertEqual(261, workdays(date(2004, 1, 1), date(2004, 12, 31)))
self.assertEqual(260, workdays(date(2005, 1, 1), date(2005, 12, 31)))
self.assertEqual(260, workdays(date(2006, 1, 1), date(2006, 12, 31)))
self.assertEqual(260, workdays(date(2007, 1, 1), date(2007, 12, 31)))
self.assertEqual(261, workdays(date(2008, 1, 1), date(2008, 12, 31)))
self.assertEqual(260 + 260, workdays(date(2005, 1, 1), date(2006, 12, 31)))
self.assertEqual(
260 + 260 + 260, workdays(date(2005, 1, 1), date(2007, 12, 31))
)
self.assertEqual(
260 + 260 + 260,
workdays(datetime.datetime(2005, 1, 1), datetime.datetime(2007, 12, 31)),
)
def test_workdays_german(self):
"""Simple minded tests for workdays_german()."""
date = datetime.date
self.assertEqual(
0, workdays_german(date(2007, 1, 25), date(2007, 1, 25))
) # Th - Th
self.assertEqual(
1, workdays_german(date(2007, 1, 25), date(2007, 1, 26))
) # Th - Fr
self.assertEqual(
2, workdays_german(date(2007, 1, 25), date(2007, 1, 27))
) # Th - Sa
self.assertEqual(
1, workdays_german(date(2007, 1, 26), date(2007, 1, 27))
) # Fr - Sa
self.assertEqual(
1, workdays_german(date(2007, 1, 26), date(2007, 1, 28))
) # Fr - Su
self.assertEqual(
1, workdays_german(date(2007, 1, 26), date(2007, 1, 29))
) # Fr - Mo
self.assertEqual(
0, workdays_german(date(2007, 1, 28), date(2007, 1, 29))
) # Su - Mo
self.assertEqual(
2, workdays_german(date(2007, 1, 26), date(2007, 1, 30))
) # Fr - Tu
self.assertEqual(
1, workdays_german(date(2007, 1, 28), date(2007, 1, 30))
) # Su - Tu
self.assertEqual(
0, workdays_german(date(2007, 1, 26), date(2007, 1, 26))
) # Fr - Fr
self.assertEqual(
1, workdays_german(date(2007, 1, 26), date(2007, 1, 27))
) # Fr - Sa
self.assertEqual(
1, workdays_german(date(2007, 1, 26), date(2007, 1, 28))
) # Fr - Su
self.assertEqual(
0, workdays_german(date(2007, 1, 27), date(2007, 1, 28))
) # Sa - So
self.assertEqual(
0, workdays_german(date(2007, 1, 27), date(2007, 1, 29))
) # Sa - Mo
self.assertEqual(
1, workdays_german(date(2007, 1, 27), date(2007, 1, 30))
) # Fr - Tu
self.assertEqual(3, workdays_german(date(2006, 12, 25), date(2007, 1, 1)))
self.assertEqual(1, workdays_german(date(2007, 2, 2), date(2007, 2, 5)))
self.assertEqual(252, workdays_german(date(2005, 1, 1), date(2005, 12, 31)))
self.assertEqual(250, workdays_german(date(2006, 1, 1), date(2006, 12, 31)))
self.assertEqual(249, workdays_german(date(2007, 1, 1), date(2007, 12, 31)))
self.assertEqual(251, workdays_german(date(2008, 1, 1), date(2008, 12, 31)))
# Christi Himmelfahrt
self.assertEqual(1, workdays_german(date(2007, 5, 16), date(2007, 5, 17)))
self.assertEqual(1, workdays_german(date(2007, 5, 16), date(2007, 5, 18)))
self.assertEqual(
1,
workdays_german(
datetime.datetime(2007, 5, 16), datetime.datetime(2007, 5, 18)
),
)
# Pfingsten
self.assertEqual(
1, workdays_german(date(2007, 5, 24), date(2007, 5, 25))
) # Th - Fr
self.assertEqual(
1, workdays_german(date(2007, 5, 25), date(2007, 5, 26))
) # Fr - Sa
self.assertEqual(
1, workdays_german(date(2007, 5, 25), date(2007, 5, 27))
) # Fr - So
self.assertEqual(
1, workdays_german(date(2007, 5, 25), date(2007, 5, 28))
) # Fr - Mo
self.assertEqual(
1, workdays_german(date(2007, 5, 25), date(2007, 5, 29))
) # Fr - Tu
# Christi Himmelfahrt
self.assertEqual(1, workdays_german(date(2007, 6, 6), date(2007, 6, 7)))
self.assertEqual(1, workdays_german(date(2007, 6, 6), date(2007, 6, 8)))
self.assertEqual(
252 + 250, workdays_german(date(2005, 1, 1), date(2006, 12, 31))
)
self.assertEqual(
252 + 250 + 249, workdays_german(date(2005, 1, 1), date(2007, 12, 31))
)
self.assertEqual(
252 + 250 + 249,
workdays_german(
datetime.datetime(2005, 1, 1), datetime.datetime(2007, 12, 31)
),
)
def test_is_workday_german(self):
self.assertTrue(is_workday_german(datetime.date(2011, 4, 21))) # Gründonnerstag
self.assertFalse(is_workday_german(datetime.date(2011, 4, 22))) # karfreitag
self.assertTrue(is_workday_german(datetime.datetime(2011, 4, 21, 0, 0)))
self.assertFalse(is_workday_german(datetime.datetime(2011, 4, 22, 0, 0)))
def test_next_workday_german(self):
"""Simple minded tests for next_workday_german()."""
date = datetime.date
self.assertEqual(
date(2007, 5, 21), next_workday_german(date(2007, 5, 18))
) # Fr
self.assertEqual(
date(2007, 5, 22), next_workday_german(date(2007, 5, 21))
) # Mo
self.assertEqual(
date(2007, 5, 25), next_workday_german(date(2007, 5, 24))
) # Th
# Pfingsten
self.assertEqual(
date(2007, 5, 29), next_workday_german(date(2007, 5, 25))
) # Fr
self.assertEqual(
date(2007, 5, 29), next_workday_german(date(2007, 5, 26))
) # Sa
self.assertEqual(
date(2007, 5, 29), next_workday_german(date(2007, 5, 27))
) # Su
self.assertEqual(
date(2007, 5, 29), next_workday_german(date(2007, 5, 28))
) # Mo ( Holiday)
self.assertEqual(date(2007, 5, 31), next_workday_german(date(2007, 5, 30)))
self.assertEqual(
datetime.datetime(2007, 5, 31),
next_workday_german(datetime.datetime(2007, 5, 30)),
)
def test_add_workdays_german(self):
"""Simple minded tests for add_workdays_german,"""
date = datetime.date
self.assertEqual(date(2008, 11, 24), add_workdays_german(date(2008, 11, 24), 0))
self.assertEqual(date(2008, 11, 25), add_workdays_german(date(2008, 11, 24), 1))
self.assertEqual(date(2008, 12, 1), add_workdays_german(date(2008, 11, 24), 5))
self.assertEqual(
date(2008, 11, 21), add_workdays_german(date(2008, 11, 24), -1)
)
self.assertEqual(
date(2008, 11, 14), add_workdays_german(date(2008, 11, 24), -6)
)
self.assertEqual(
datetime.datetime(2008, 11, 14),
add_workdays_german(datetime.datetime(2008, 11, 24), -6),
)
class _ApiTests(unittest.TestCase):
def test_defaults(self):
"""Test rfc3339_date defaults"""
rfc3339_date()
rfc2616_date()
class _DateTruncTestCase(unittest.TestCase):
"""Unittests for date_trunc"""
def test_truncate_year(self):
self.assertEqual(
date_trunc('year', datetime.datetime(1980, 5, 4)),
datetime.datetime(1980, 1, 1),
)
self.assertEqual(
date_trunc('year', datetime.datetime(1980, 5, 4)).date(),
datetime.date(1980, 1, 1),
)
self.assertEqual(
date_trunc('year', datetime.date(1980, 5, 4)), datetime.date(1980, 1, 1)
)
self.assertEqual(
date_trunc('year', datetime.date(1980, 5, 4)), datetime.date(1980, 1, 1)
)
def test_truncate_tertial(self):
self.assertEqual(
date_trunc('tertial', datetime.datetime(2011, 4, 30)),
datetime.datetime(2011, 1, 1),
)
self.assertEqual(
date_trunc('tertial', datetime.datetime(2011, 4, 30)).date(),
datetime.date(2011, 1, 1),
)
self.assertEqual(
date_trunc('tertial', datetime.date(2011, 5, 1)), datetime.date(2011, 5, 1)
)
self.assertEqual(
date_trunc('tertial', datetime.date(2011, 8, 31)), datetime.date(2011, 5, 1)
)
self.assertEqual(
date_trunc('tertial', datetime.date(2011, 9, 1)), datetime.date(2011, 9, 1)
)
def test_truncate_quarter(self):
self.assertEqual(
date_trunc('quarter', datetime.datetime(1945, 2, 19)),
datetime.datetime(1945, 1, 1),
)
self.assertEqual(
date_trunc('quarter', datetime.datetime(1945, 2, 19)).date(),
datetime.date(1945, 1, 1),
)
self.assertEqual(
date_trunc('quarter', datetime.date(1945, 2, 19)), datetime.date(1945, 1, 1)
)
self.assertEqual(
date_trunc('quarter', datetime.date(1945, 2, 19)), datetime.date(1945, 1, 1)
)
self.assertEqual(
date_trunc('quarter', datetime.datetime(1980, 5, 4)),
datetime.datetime(1980, 4, 1),
)
self.assertEqual(
date_trunc('quarter', datetime.datetime(1980, 5, 4)).date(),
datetime.date(1980, 4, 1),
)
self.assertEqual(
date_trunc('quarter', datetime.date(1980, 5, 4)), datetime.date(1980, 4, 1)
)
self.assertEqual(
date_trunc('quarter', datetime.date(1980, 5, 4)), datetime.date(1980, 4, 1)
)
self.assertEqual(
date_trunc('quarter', datetime.datetime(1951, 7, 22)),
datetime.datetime(1951, 7, 1),
)
self.assertEqual(
date_trunc('quarter', datetime.datetime(1951, 7, 22)).date(),
datetime.date(1951, 7, 1),
)
self.assertEqual(
date_trunc('quarter', datetime.date(1951, 7, 22)), datetime.date(1951, 7, 1)
)
self.assertEqual(
date_trunc('quarter', datetime.date(1951, 7, 22)), datetime.date(1951, 7, 1)
)
self.assertEqual(
date_trunc('quarter', datetime.datetime(2000, 12, 31)),
datetime.datetime(2000, 10, 1),
)
self.assertEqual(
date_trunc('quarter', datetime.datetime(2000, 12, 31)).date(),
datetime.date(2000, 10, 1),
)
self.assertEqual(
date_trunc('quarter', datetime.date(2000, 12, 31)),
datetime.date(2000, 10, 1),
)
self.assertEqual(
date_trunc('quarter', datetime.date(2000, 12, 31)),
datetime.date(2000, 10, 1),
)
def test_truncate_month(self):
self.assertEqual(
date_trunc('month', datetime.datetime(1978, 6, 12)),
datetime.datetime(1978, 6, 1),
)
self.assertEqual(
date_trunc('month', datetime.datetime(1978, 6, 12)).date(),
datetime.date(1978, 6, 1),
)
self.assertEqual(
date_trunc('month', datetime.date(1978, 6, 12)), datetime.date(1978, 6, 1)
)
self.assertEqual(
date_trunc('month', datetime.date(1978, 6, 12)), datetime.date(1978, 6, 1)
)
def test_truncate_week(self):
self.assertEqual(
date_trunc('week', datetime.datetime(2000, 1, 1)),
datetime.datetime(1999, 12, 27),
)
self.assertEqual(
date_trunc('week', datetime.datetime(2000, 1, 1)).date(),
datetime.date(1999, 12, 27),
)
self.assertEqual(
date_trunc('week', datetime.date(2000, 1, 1)), datetime.date(1999, 12, 27)
)
self.assertEqual(
date_trunc('week', datetime.date(2000, 1, 1)), datetime.date(1999, 12, 27)
)
def test_truncate_day(self):
self.assertEqual(
date_trunc('day', datetime.datetime(2006, 2, 25, 23, 17, 40)),
datetime.datetime(2006, 2, 25),
)
self.assertEqual(
date_trunc('day', datetime.datetime(2006, 2, 25)),
datetime.datetime(2006, 2, 25),
)
self.assertEqual(
date_trunc('day', datetime.date(2006, 2, 25)), datetime.date(2006, 2, 25)
)
self.assertEqual(
date_trunc('day', datetime.date(2006, 2, 25)), datetime.date(2006, 2, 25)
)
def test_truncate_hour(self):
self.assertEqual(
date_trunc('hour', datetime.datetime(2006, 2, 25, 23, 17, 40)),
datetime.datetime(2006, 2, 25, 23),
)
self.assertEqual(
date_trunc('hour', datetime.datetime(2006, 2, 25, 23, 17, 40)),
datetime.datetime(2006, 2, 25, 23, 0, 0),
)
self.assertEqual(
date_trunc('hour', datetime.date(2006, 2, 25)), datetime.date(2006, 2, 25)
)
self.assertEqual(
date_trunc('hour', datetime.date(2006, 2, 25)), datetime.date(2006, 2, 25)
)
def test_truncate_minute(self):
self.assertEqual(
date_trunc('minute', datetime.datetime(2006, 2, 25, 23, 17, 40)),
datetime.datetime(2006, 2, 25, 23, 17, 0),
)
self.assertEqual(
date_trunc('minute', datetime.date(2006, 2, 25)), datetime.date(2006, 2, 25)
)
self.assertEqual(
date_trunc('minute', datetime.date(2006, 2, 25)), datetime.date(2006, 2, 25)
)
def test_truncate_second(self):
self.assertEqual(
date_trunc('second', datetime.datetime(2006, 2, 25, 23, 17, 40)),
datetime.datetime(2006, 2, 25, 23, 17, 40),
)
self.assertEqual(
date_trunc('second', datetime.date(2006, 2, 25)), datetime.date(2006, 2, 25)
)
self.assertEqual(
date_trunc('second', datetime.date(2006, 2, 25)), datetime.date(2006, 2, 25)
)
def test_invalid(self):
self.assertRaises(ValueError, date_trunc, 'alex', datetime.datetime.now())
if __name__ == '__main__':
failure_count, test_count = doctest.testmod()
unittest.main()
sys.exit(failure_count)