# functions related to Date-fields # ----------------------------------------------------- """ additionally functions for calculating date with formulas like [DATE+2M] and for comparison of date related on two reference-dates """ import datetime #from dateutil.relativedelta import relativedelta import re import utils.data_const as D F_DIR = "%Y-%m-%d_%H-%M-%S" F_DE = "%d.%m.%Y" F_N8 = "%Y%m%d" def getActdate(format): return getFormatdate(datetime.datetime.now(), format) def getFormatdate(date, format): """ it return the date as string in the format """ return date.strftime(format) def getFormatDatetupel(dtupel, format): """ it return the date as string in the format """ if format == F_N8: return f'{dtupel[0]:04}'+f'{dtupel[1]:02}'+f'{dtupel[2]:02}' return getFormatdate(datetime.datetime(dtupel[0], dtupel[1], dtupel[2], dtupel[3], dtupel[4], dtupel[5]) ,format) def parseFormula(instring): """ the function parses the string as a formula. In the formula the input-date - actdate or explicite date - will be added resp. subtracted with years, months or dates which are specified in the formula. The structure of the formula: DATE +/- mY +/-nM +/-qD :param instring: :return: """ instring = instring.upper() if instring[2:6] == "DATE": refdate = datetime.datetime.today() formula = instring[7:-2].upper() else: dstring = instring[2:instring.find(" ")] res = parseDate(dstring) refdate = datetime.datetime(res[0], res[1], res[2], res[3], res[4], res[5]) formula = instring[2+len(dstring):-2] formula = re.sub(r' ', '', formula) year = refdate.year mon = refdate.month day = refdate.day hour = refdate.hour min = refdate.minute sec = refdate.second if re.match(r"[-+]\d+[JYMDT]", formula): ress = re.compile(r"([-+])(\d+)([JYMDT])") for res in ress.finditer(formula): summand = int(res.group(2)) if res.group(1) == "-": summand = summand * (-1) if res.group(3) in "JY": year = year + summand if res.group(3) in "M": mon = mon + summand while mon <= 0: mon = mon + 12 year = year - 1 while mon > 12: mon = mon - 12 year = year + 1 if res.group(3) in "DT": refdate = datetime.datetime(year, mon, day, hour, min, sec) refdate = refdate + datetime.timedelta(days=summand) year = refdate.year mon = refdate.month day = refdate.day hour = refdate.hour min = refdate.minute sec = refdate.second return (year, mon, day, hour, min, sec) else: print("re matcht nicht") return (year, mon, day, hour, min, sec) def parseDate(instring): """ the function parses the string as a date or timestamp which is formed in one of the typical formates :param the string to be parse: :return timestamp as tupel (y, m, d, H, M ,S): """ year = 0 mon = 0 day = 0 hour = 0 min = 0 sec = 0 if instring[0:2] == "{(" and instring[-2:] == ")}": return parseFormula(instring) for d in ["_", " "]: if d in instring and instring.find(d) > 8: dstring = instring[0:instring.find(d)] tstring = instring[instring.find(d)+1:] dres = parseDate(dstring) tres = parseDate(tstring) return (dres[0], dres[1], dres[2], tres[3], tres[4], tres[5]) if re.match(r"\d{4}[-./]\d{2}[-./]\d{2}", instring): res = re.match(r"(\d{4})[-./](\d{2})[-./](\d{2})", instring) year = int(res.group(1)) mon = int(res.group(2)) day = int(res.group(3)) return (year, mon, day, hour, min, sec) if re.match(r"\d{1,2}[-./]\d{1,2}[-./]\d{1,2}", instring): res = re.match(r"(\d{1,2})[-./](\d{1,2})[-./](\d{4})", instring) year = int(res.group(3)) mon = int(res.group(2)) day = int(res.group(1)) return (year, mon, day, hour, min, sec) if re.match(r"\d{8}", instring): year = instring[0:4] mon = instring[4:6] day = instring[6:8] return (year, mon, day, hour, min, sec) if re.match(r"\d{2}[-:]\d{2}[-:/]\d{2}", instring): res = re.match(r"(\d{2})[-:/](\d{2})[-:/](\d{2})", instring) hour = int(res.group(1)) min = int(res.group(2)) sec = int(res.group(3)) return (year, mon, day, hour, min, sec)