Source code for metrics.date_utils

"""Various date utility functions"""

import numpy as np
import pandas as pd


[docs]def weekdays(from_date: str, to_date: str): """Returns the number of weekdays between the dates using np""" return np.busday_count(from_date, str(lookAhead(1, to_date).date()), weekmask="1111100")
[docs]def lookAhead(offset: int, from_date: str = pd.Timestamp.today()): return pd.Timestamp(from_date).floor("D") + pd.offsets.Day(offset)
[docs]def lookBack(offset: int, from_date: str = pd.Timestamp.today()): return pd.Timestamp(from_date).floor("D") - pd.offsets.Day(offset)
[docs]def monthBegin(from_date: str = pd.Timestamp.today()): """Return with the first for the date""" return pd.Timestamp(from_date).strftime("%Y-%m-01")
[docs]def leapYear(year: int) -> bool: """return True for leap years""" return ((year % 4 == 0) and (year % 100 != 0)) or (year % 400 == 0)
[docs]def lastMonthDay(month: str) -> str: """expects YYYY-MM as input returns YYYY-MM-XX where XX is the last day for month MM""" y, m = month.split("-") day = 30 if m == "02": if leapYear(int(y)): day = 29 else: day = 28 if m in ["01", "03", "05", "07", "08", "10", "12"]: day = 31 return f"{month}-{day}"
[docs]def splitMonthTable(df: pd.DataFrame) -> pd.DataFrame: """split the table into two entries per month""" first = df.copy() first["Month"] = [pd.Timestamp(f"{x}-01") for x in first["Month"]] last = df.copy() last["Month"] = [pd.Timestamp(lastMonthDay(x)) for x in last["Month"]] result = pd.concat([first, last], ignore_index=True, sort=True) result["WeeklyExtCost"] = result["External_cost"] * 12 / 52 if "Real_income" in result: result["WeeklyIn"] = result["Real_income"] * 12 / 52 result["Year"] = result["Month"].dt.strftime("%Y") return result.sort_values(by=["Month"])