Skip to content

arguments

arguments

parse_date

parse_date(value: str, formatting='%Y-%m-%d', tz_name: str = 'Europe/Madrid', assume_tz: str = 'UTC', return_naive: bool = True)

Parse a date/datetime string and convert to Europe/Madrid with DST awareness.

  • value: e.g. "2024-08-31T22:00:00Z" or "2024-08-31"
  • tz_name: target timezone (default Europe/Madrid)
  • assume_tz: if input is naive (date-only), treat it as this tz ("UTC" or any IANA tz)
  • return_naive: if True, drop tzinfo after conversion (keeps local wall time)
Source code in source/src/arguments.py
def parse_date(
    value: str,
    formatting="%Y-%m-%d",
    tz_name: str = "Europe/Madrid",
    assume_tz: str = "UTC",
    return_naive: bool = True,
):
    """
    Parse a date/datetime string and convert to Europe/Madrid with DST awareness.

    - value: e.g. "2024-08-31T22:00:00Z" or "2024-08-31"
    - tz_name: target timezone (default Europe/Madrid)
    - assume_tz: if input is naive (date-only), treat it as this tz ("UTC" or any IANA tz)
    - return_naive: if True, drop tzinfo after conversion (keeps local wall time)
    """
    v = value.strip()
    try:
        # Handle trailing 'Z' (UTC) which datetime.fromisoformat pre-3.11 doesn't accept
        if v.endswith("Z"):
            v = v[:-1] + "+00:00"

        if "T" in v or "+" in v or v.count(":") >= 1:
            # Likely a datetime
            dt = datetime.datetime.fromisoformat(v)
        else:
            # Likely a date-only string
            dt = datetime.datetime.strptime(v, formatting)

        if return_naive:
            return dt.replace(tzinfo=None)

        # If naive (no tzinfo), assign the assumed timezone
        if dt.tzinfo is None:
            dt = dt.replace(tzinfo=ZoneInfo(assume_tz))

        # Convert to target local timezone (DST handled automatically)
        local_dt = dt.astimezone(ZoneInfo(tz_name))


        return local_dt

    except Exception as e:
        raise ArgumentDateError(
            f'The value "{value}" could not be parsed/converted: {e}'
        ) from e

parse_arguments

parse_arguments()

Parse and validate command-line arguments

Source code in source/src/arguments.py
def parse_arguments():
    """Parse and validate command-line arguments"""
    parser = argparse.ArgumentParser(description="Justicier")

    parser.add_argument("-r", "--request", "--id", type=parse_id, required=False,
                        help='ID of the justification request in Microsoft List of Peticions Justificacions. If you use'
                             ' this argument you can\'t use any other argument to submit data to the algorithm except '
                             ' for -l / --location ')

    parser.add_argument("-l", "--location", type=parse_input_type, required=False, default="sharepoint",
                        help="Location of the input data. Possible values are: \"sharepoint\" to download from "
                             "sharepoint location and \"local\" to use the local file system storage and read the input"
                             " folder in the repository root folder.")
    parser.add_argument("-L", "--input-location", type=parse_input_location, required=False,
                        default=os.path.join(ROOT_FOLDER, "input"),
                        help="Path location of input data. If used, --location local is assumed.")

    parser.add_argument("-n", "--naf", "--NAF", type=parse_naf, required=False,
                        help="NAF (SS security number) of the employee to justify")
    parser.add_argument("-N", "--name", type=parse_name_a3, required=False,
                        help="Name of the employee to justify")
    parser.add_argument("-t", "--target-email", type=parse_email_a3, required=False,
                        help="Email of the employee to justify")
    parser.add_argument("-d", "--dni", "--DNI", type=parse_dni, required=False,
                        help="Name of the employee to justify")

    parser.add_argument("-b", "--begin", type=parse_date, required=False, help="Begin date (YYYY-MM-DD)")
    parser.add_argument("-e", "--end", type=parse_date, required=False, help="End date (YYYY-MM-DD)")
    parser.add_argument("-a", "--author", type=parse_author, required=False, help="author's email doing"
                                                                                  " request")

    parser.add_argument("-s", "--merge-salary", type=parse_boolean, required=False, default=False,
                        help="Merge each salary with the corresponding bank proof")
    parser.add_argument("-m", "--merge-result", type=parse_boolean, required=False,
                        default=get_compact_init(),
                        help="Comma separated list of values that indicate which documents need to be merged in one "
                             "single PDF in the output. Possible values are: " +
                             ",".join([dt.value.__str__() for dt in DocType]))
    parser.add_argument("-R", "--merge-rnt-rlc", type=parse_boolean, required=False, default=False,
                        help="Merge all RLCs and RNTs of each month.")

    args = parser.parse_args()

    return args