Commit 65039cae authored by Guillaume Michon's avatar Guillaume Michon

Added some methods, and corrected some bugs in date functions


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@2893 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent e7c48ada
...@@ -27,8 +27,8 @@ ...@@ -27,8 +27,8 @@
############################################################################## ##############################################################################
from DateTime import DateTime from DateTime import DateTime
from zLOG import LOG
# Date methods - XXX They should be moved elsewhere in the future
millis = DateTime('2000/01/01 12:00:00.001') - DateTime('2000/01/01 12:00:00') millis = DateTime('2000/01/01 12:00:00.001') - DateTime('2000/01/01 12:00:00')
centis = millis * 10 centis = millis * 10
number_of_months_in_year = 12. number_of_months_in_year = 12.
...@@ -51,11 +51,9 @@ def addToDate(date,to_add=None, **kw): ...@@ -51,11 +51,9 @@ def addToDate(date,to_add=None, **kw):
if to_add is not None: if to_add is not None:
kw.update(to_add) kw.update(to_add)
to_add = kw to_add = kw
#to_add.update(kw)
for key in ('year', 'month', 'day', 'hour', 'minute', 'second'): for key in ('year', 'month', 'day', 'hour', 'minute', 'second'):
method = getattr(date, key) method = getattr(date, key)
return_value[key] = method() return_value[key] = method()
saved_day = return_value['day']
larger_key_dict = { 'second':'minute', 'minute':'hour', 'hour':'day', 'month':'year' } larger_key_dict = { 'second':'minute', 'minute':'hour', 'hour':'day', 'month':'year' }
number_of_in_dict = { 'second' : number_of_seconds_in_minute, number_of_in_dict = { 'second' : number_of_seconds_in_minute,
'minute' : number_of_minutes_in_hour, 'minute' : number_of_minutes_in_hour,
...@@ -76,10 +74,10 @@ def addToDate(date,to_add=None, **kw): ...@@ -76,10 +74,10 @@ def addToDate(date,to_add=None, **kw):
if to_add.get('year', None) is not None: if to_add.get('year', None) is not None:
return_value['year'] = return_value['year'] + to_add['year'] return_value['year'] = return_value['year'] + to_add['year']
day_to_add = return_value['day'] - saved_day day_to_add = return_value['day'] - 1
if to_add.get('day', None) is not None: if to_add.get('day', None) is not None:
day_to_add += to_add['day'] day_to_add += to_add['day']
return_value['day'] = saved_day return_value['day'] = 1
return_date = DateTime('%i/%i/%i %i:%i:%d' % (return_value['year'], return_date = DateTime('%i/%i/%i %i:%i:%d' % (return_value['year'],
return_value['month'], return_value['month'],
return_value['day'], return_value['day'],
...@@ -90,7 +88,7 @@ def addToDate(date,to_add=None, **kw): ...@@ -90,7 +88,7 @@ def addToDate(date,to_add=None, **kw):
return return_date return return_date
def getClosestDate(date=None, target_date=None, precision='month', before=1): def getClosestDate(date=None, target_date=None, precision='month', before=1, strict=1):
""" """
Return the closest date from target_date, at the given precision. Return the closest date from target_date, at the given precision.
If date is set, the search is made by making steps of 'precision' duration. If date is set, the search is made by making steps of 'precision' duration.
...@@ -115,21 +113,19 @@ def getClosestDate(date=None, target_date=None, precision='month', before=1): ...@@ -115,21 +113,19 @@ def getClosestDate(date=None, target_date=None, precision='month', before=1):
target_date = DateTime() target_date = DateTime()
earlier_target_date = target_date - millis earlier_target_date = target_date - millis
if DateTime(earlier_target_date.Date()) == DateTime(target_date.Date()):
target_date = earlier_target_date
# date = DateTime(date.Date())
# target_date = DateTime(target_date.Date())
to_check = { 'day':{'year':1, 'month':1, 'day':1}, 'month':{'year':1, 'month':1}, 'year':{'year':1} } to_check = { 'day':{'year':1, 'month':1, 'day':1}, 'month':{'year':1, 'month':1}, 'year':{'year':1} }
diff_value = {} diff_value = {}
diff_value = getIntervalBetweenDates(from_date = date, to_date = target_date, keys=to_check[precision]) diff_value = getIntervalBetweenDates(from_date = date, to_date = target_date, keys=to_check[precision])
return_date = addToDate(date = date, to_add = diff_value) return_date = addToDate(date = date, to_add = diff_value)
while return_date - target_date < 0: while (strict and return_date - target_date < 0) or \
(not strict and \
getIntervalBetweenDates(from_date=return_date, to_date=target_date, keys={'day':1})['day'] > 0):
return_date = addToDate(date = return_date, to_add = { precision:1 }) return_date = addToDate(date = return_date, to_add = { precision:1 })
if before and DateTime(return_date.Date()) != DateTime(target_date.Date()) : if before and DateTime(return_date.Date()) != DateTime(target_date.Date()) :
return_date = addToDate(date = return_date, to_add = { precision:-1 }) return_date = addToDate(date = return_date, to_add = { precision:-1 })
return return_date return return_date
...@@ -228,7 +224,7 @@ def getMonthFraction(date, days): ...@@ -228,7 +224,7 @@ def getMonthFraction(date, days):
return days / number_of_days_in_month return days / number_of_days_in_month
def getYearFraction(date, days=None, months=None): def getYearFraction(days=None, months=None, days_in_year=number_of_days_in_year):
""" """
Return a ratio corresponding to the fraction of the year Return a ratio corresponding to the fraction of the year
represented by the given number of days OR the number of months. represented by the given number of days OR the number of months.
...@@ -236,12 +232,30 @@ def getYearFraction(date, days=None, months=None): ...@@ -236,12 +232,30 @@ def getYearFraction(date, days=None, months=None):
if days is None and months is not None: if days is None and months is not None:
return months / number_of_months_in_year return months / number_of_months_in_year
else: else:
return days / number_of_days_in_year return days / days_in_year
def getBissextilCompliantYearFraction(from_date=None, to_date=None, reference_date=DateTime('2000/01/01')):
"""
Returns a ratio corresponding to the fraction of the year
represented by the number of days between both of the given dates.
This method takes care of bissextil years
reference_date is used to replace the civil year by the financial year
This method must not be used with a date difference higher than a year
"""
interval = getIntervalBetweenDates(from_date, to_date, keys={'year':1, 'day':1})
reference_date = getClosestDate(date=reference_date, target_date=from_date, precision='year', before=1)
days_in_year = getIntervalBetweenDates(reference_date,
addToDate(reference_date, year=1),
keys={'day':1})['day']
return_value = interval['year'] + getYearFraction(days=interval['day'], days_in_year=days_in_year)
return return_value
def getDecimalNumberOfYearsBetween(from_date, to_date, reference_date=DateTime('2000/01/01')): def getDecimalNumberOfYearsBetween(from_date, to_date, reference_date=DateTime('2000/01/01')):
""" """
Return a number of float representing the number of years between Return a float representing the number of years between
the both given dates. the both given dates.
""" """
first_date = getClosestDate(target_date = from_date, date = reference_date, before = 0, precision='year') first_date = getClosestDate(target_date = from_date, date = reference_date, before = 0, precision='year')
...@@ -252,8 +266,8 @@ def getDecimalNumberOfYearsBetween(from_date, to_date, reference_date=DateTime(' ...@@ -252,8 +266,8 @@ def getDecimalNumberOfYearsBetween(from_date, to_date, reference_date=DateTime('
last_date = addToDate(last_date, {'year':1}) last_date = addToDate(last_date, {'year':1})
interval_year = getIntervalBetweenDates(first_date, last_date, {'year':1} )['year'] interval_year = getIntervalBetweenDates(first_date, last_date, {'year':1} )['year']
fraction = getYearFraction(first_date, days=getIntervalBetweenDates(from_date, first_date, {'day':1})['day']) fraction = getYearFraction(days=getIntervalBetweenDates(from_date, first_date, {'day':1})['day'])
fraction += getYearFraction(to_date, days=getIntervalBetweenDates(last_date, to_date, {'day':1})['day']) fraction += getYearFraction(days=getIntervalBetweenDates(last_date, to_date, {'day':1})['day'])
fraction += interval_year fraction += interval_year
...@@ -270,5 +284,3 @@ def roundMonthToGreaterEntireYear(months_number): ...@@ -270,5 +284,3 @@ def roundMonthToGreaterEntireYear(months_number):
years_number += 1 years_number += 1
return int(years_number) * 12 return int(years_number) * 12
# End of date methods
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment