Skip to content

date_utile

date_utile

sanitize_date

sanitize_date(date_dirty: Any) -> datetime.datetime

Normalizes a raw Excel cell value into a Madrid-tz-aware datetime.

Handles the value shapes pandas/openpyxl can hand back for a date cell: a pandas.Timestamp or datetime.datetime (tz-aware or naive), pd.NaT, a dd/mm/yyyy-formatted string, an empty/NaN float cell, or None. A missing/empty date is treated as a permanent contract, per core/defines.PERMANENT_CONTRACT_DATE.

Parameters:

Name Type Description Default
date_dirty Any

The raw cell value to sanitize.

required

Returns:

Type Description
datetime

datetime.datetime: A timezone-aware datetime pinned to MADRID_TZ.

Raises:

Type Description
ValueError

If date_dirty is of a type this function doesn't know how to interpret.

Source code in source/src/imarina_load_researchers/core/date_utile.py
def sanitize_date(date_dirty: Any) -> datetime.datetime:
    """
    Normalizes a raw Excel cell value into a Madrid-tz-aware datetime.

    Handles the value shapes pandas/openpyxl can hand back for a date cell:
    a `pandas.Timestamp` or `datetime.datetime` (tz-aware or naive), `pd.NaT`,
    a `dd/mm/yyyy`-formatted string, an empty/`NaN` float cell, or `None`.
    A missing/empty date is treated as a permanent contract, per
    `core/defines.PERMANENT_CONTRACT_DATE`.

    Args:
        date_dirty (Any): The raw cell value to sanitize.

    Returns:
        datetime.datetime: A timezone-aware datetime pinned to `MADRID_TZ`.

    Raises:
        ValueError: If `date_dirty` is of a type this function doesn't know
            how to interpret.
    """
    if isinstance(date_dirty, pd.Timestamp) or type(date_dirty) is datetime.datetime:
        # Excel stores no timezone; these values are Madrid wall-clock times,
        # same as the string-parsed branch below and PERMANENT_CONTRACT_DATE
        # (core/defines.py), which callers compare/subtract this against.
        if date_dirty.tzinfo is None:
            return date_dirty.replace(tzinfo=MADRID_TZ)
        return date_dirty
    elif date_dirty is pd.NaT:
        return PERMANENT_CONTRACT_DATE
    elif isinstance(date_dirty, str):
        return datetime.datetime.strptime(date_dirty.strip("'"), "%d/%m/%Y").replace(
            tzinfo=MADRID_TZ
        )
    elif isinstance(date_dirty, float) or date_dirty is None:
        return PERMANENT_CONTRACT_DATE
    else:
        raise ValueError(
            "Unknown type for date to sanitize: "
            + str(type(date_dirty))
            + " value is: "
            + str(date_dirty)
        )

unparse_date

unparse_date(date: datetime | None) -> str

Formats a datetime back into the output spreadsheet's date string format.

Parameters:

Name Type Description Default
date datetime | None

The date to format, or None.

required

Returns:

Name Type Description
str str

date formatted per core/defines.DATE_FORMAT, or "" if date is None.

Source code in source/src/imarina_load_researchers/core/date_utile.py
def unparse_date(date: datetime.datetime | None) -> str:
    """
    Formats a datetime back into the output spreadsheet's date string format.

    Args:
        date (datetime.datetime | None): The date to format, or `None`.

    Returns:
        str: `date` formatted per `core/defines.DATE_FORMAT`, or `""` if
            `date` is `None`.
    """
    if date is None:
        return ""
    else:
        return date.strftime(DATE_FORMAT)