AIL-framework/bin/packages/Date.py

261 lines
9.3 KiB
Python

#!/usr/bin/python3
import datetime
from calendar import monthrange
from dateutil.rrule import rrule, MONTHLY
from dateutil.relativedelta import relativedelta
def convert_date_str_to_datetime(date_str):
res = datetime.date(int(date_str[0:4]), int(date_str[4:6]), int(date_str[6:8]))
return res
def get_full_month_str(date_from, date_to):
# add one day (if last day of the month)
date_to = date_to + relativedelta(days=+1)
full_month = [dt for dt in rrule(MONTHLY, bymonthday=1,dtstart=date_from, until=date_to)]
# remove last_month (incomplete)
if len(full_month):
full_month = full_month[:-1]
return full_month
def get_date_range_full_month_and_days(date_from, date_to):
date_from = convert_date_str_to_datetime(date_from)
date_to = convert_date_str_to_datetime(date_to)
full_month = get_full_month_str(date_from, date_to)
# request at least one month
if full_month:
day_list = substract_date(date_from.strftime('%Y%m%d'), full_month[0].strftime('%Y%m%d'))
# remove last day (day in full moth)
if day_list:
day_list = day_list[:-1]
day_list.extend(substract_date( (full_month[-1] + relativedelta(months=+1) ).strftime('%Y%m%d'), date_to.strftime('%Y%m%d')))
else:
day_list = substract_date(date_from.strftime('%Y%m%d'), date_to.strftime('%Y%m%d'))
full_month = [dt_month.strftime('%Y%m') for dt_month in full_month]
return day_list, full_month
# # TODO: refractor me
class Date(object):
"""docstring for Date"""
def __init__(self, *args):
if len(args) == 3:
self.year = str(args[0])
self.month = str(args[1])
self.day = str(args[2]).zfill(2)
if len(args) == 1:
self.year = str(args[0])[:4]
self.month = str(args[0])[4:6]
self.day = str(args[0])[6:]
def __str__(self):
return "{0}{1}{2}".format(self.year, self.month, self.day)
def _get_year(self):
return self.year
def _get_month(self):
return self.month
def _get_day(self):
return self.day
def _set_year(self, year):
self.year = year
def _set_month(self, month):
self.month = month
def _set_day(self, day):
self.day = day
def substract_day(self, numDay):
computed_date = datetime.date(int(self.year), int(self.month), int(self.day)) - datetime.timedelta(numDay)
comp_year = str(computed_date.year)
comp_month = str(computed_date.month).zfill(2)
comp_day = str(computed_date.day).zfill(2)
return comp_year + comp_month + comp_day
def get_today_date_str(separator=False):
if separator:
return datetime.date.today().strftime("%Y/%m/%d")
else:
return datetime.date.today().strftime("%Y%m%d")
def get_current_week_day():
dt = datetime.date.today()
start = dt - datetime.timedelta(days=dt.weekday())
return start.strftime("%Y%m%d")
def get_month_dates(date=None):
if date:
date = convert_date_str_to_datetime(date)
else:
date = datetime.date.today()
num_days = monthrange(date.year, date.month)[1]
return [datetime.date(date.year, date.month, day).strftime("%Y%m%d") for day in range(1, num_days+1)]
def get_date_week_by_date(date):
dt = datetime.date(int(date[0:4]), int(date[4:6]), int(date[6:8]))
start = dt - datetime.timedelta(days=dt.weekday())
return start.strftime("%Y%m%d")
def date_add_day(date, num_day=1):
new_date = datetime.date(int(date[0:4]), int(date[4:6]), int(date[6:8])) + datetime.timedelta(num_day)
new_date = str(new_date).replace('-', '')
return new_date
def daterange_add_days(date, nb_days):
end_date = date_add_day(date, num_day=nb_days)
return get_daterange(date, end_date)
def date_substract_day(date, num_day=1):
new_date = datetime.date(int(date[0:4]), int(date[4:6]), int(date[6:8])) - datetime.timedelta(num_day)
new_date = str(new_date).replace('-', '')
return new_date
# # TODO: remove me ## FIXME:
def get_date_range(num_day):
curr_date = datetime.date.today()
date = Date(str(curr_date.year)+str(curr_date.month).zfill(2)+str(curr_date.day).zfill(2))
date_list = []
for i in range(0, num_day+1):
date_list.append(date.substract_day(i))
return list(reversed(date_list))
def get_previous_date_list(num_day):
curr_date = datetime.date.today()
date = Date(str(curr_date.year)+str(curr_date.month).zfill(2)+str(curr_date.day).zfill(2))
date_list = []
for i in range(0, num_day+1):
date_list.append(date.substract_day(i))
return list(reversed(date_list))
def get_nb_days_by_daterange(date_from, date_to):
date_from = datetime.date(int(date_from[0:4]), int(date_from[4:6]), int(date_from[6:8]))
date_to = datetime.date(int(date_to[0:4]), int(date_to[4:6]), int(date_to[6:8]))
delta = date_to - date_from # timedelta
return len(range(delta.days + 1))
def get_date_range_today(date_from):
return substract_date(date_from, get_today_date_str())
def substract_date(date_from, date_to):
date_from = datetime.date(int(date_from[0:4]), int(date_from[4:6]), int(date_from[6:8]))
date_to = datetime.date(int(date_to[0:4]), int(date_to[4:6]), int(date_to[6:8]))
delta = date_to - date_from # timedelta
l_date = []
for i in range(delta.days + 1):
date = date_from + datetime.timedelta(i)
l_date.append( date.strftime('%Y%m%d') )
return l_date
def get_daterange(date_from, date_to):
date_from = datetime.date(int(date_from[0:4]), int(date_from[4:6]), int(date_from[6:8]))
date_to = datetime.date(int(date_to[0:4]), int(date_to[4:6]), int(date_to[6:8]))
delta = date_to - date_from # timedelta
l_date = []
for i in range(delta.days + 1):
date = date_from + datetime.timedelta(i)
l_date.append(date.strftime('%Y%m%d'))
return l_date
def validate_str_date(str_date, separator=''):
try:
datetime.datetime.strptime(str_date, '%Y{}%m{}%d'.format(separator, separator))
return True
except ValueError:
return False
except TypeError:
return False
def api_validate_str_date_range(date_from, date_to, separator=''):
is_date = validate_str_date(date_from, separator=separator) and validate_str_date(date_from, separator=separator)
if not is_date:
return ({"status": "error", "reason": "Invalid Date"}, 400)
if int(date_from) > int(date_to):
return ({"status": "error", "reason": "Invalid Date range, Date from > Date to"}, 400)
def sanitise_date_range(date_from, date_to, separator='', date_type='str'):
'''
Check/Return a correct date_form and date_to
'''
if not date_from and date_to:
date_from = date_to
elif not date_to and date_from:
date_to = date_from
elif not date_to and not date_from:
date = datetime.date.today().strftime("%Y%m%d")
return {"date_from": date, "date_to": date}
if date_type=='str':
# remove separators
if len(date_from) == 10:
date_from = date_from[0:4] + date_from[5:7] + date_from[8:10]
if len(date_to) == 10:
date_to = date_to[0:4] + date_to[5:7] + date_to[8:10]
if not validate_str_date(date_from, separator=separator):
date_from = datetime.date.today().strftime("%Y%m%d")
if not validate_str_date(date_to, separator=separator):
date_to = datetime.date.today().strftime("%Y%m%d")
else: # datetime
if isinstance(date_from, datetime.datetime):
date_from = date_from.strftime("%Y%m%d")
else:
date_from = datetime.date.today().strftime("%Y%m%d")
if isinstance(date_to, datetime.datetime):
date_to = date_to.strftime("%Y%m%d")
else:
date_to = datetime.date.today().strftime("%Y%m%d")
if int(date_from) > int(date_to):
res = date_from
date_from = date_to
date_to = res
return {"date_from": date_from, "date_to": date_to}
def sanitise_daterange(date_from, date_to, separator='', date_type='str'):
'''
Check/Return a correct date_form and date_to
'''
if not date_from and date_to:
date_from = date_to
elif not date_to and date_from:
date_to = date_from
elif not date_to and not date_from:
date = datetime.date.today().strftime("%Y%m%d")
return date, date
if date_type == 'str':
# remove separators
if len(date_from) == 10:
date_from = date_from[0:4] + date_from[5:7] + date_from[8:10]
if len(date_to) == 10:
date_to = date_to[0:4] + date_to[5:7] + date_to[8:10]
if not validate_str_date(date_from, separator=separator):
date_from = datetime.date.today().strftime("%Y%m%d")
if not validate_str_date(date_to, separator=separator):
date_to = datetime.date.today().strftime("%Y%m%d")
else: # datetime
if isinstance(date_from, datetime.datetime):
date_from = date_from.strftime("%Y%m%d")
else:
date_from = datetime.date.today().strftime("%Y%m%d")
if isinstance(date_to, datetime.datetime):
date_to = date_to.strftime("%Y%m%d")
else:
date_to = datetime.date.today().strftime("%Y%m%d")
if int(date_from) > int(date_to):
res = date_from
date_from = date_to
date_to = res
return date_from, date_to