date_operations¶
shortfx.fxDate.date_operations
¶
Date Operations Module.
This module provides comprehensive date and time manipulation utilities for Python applications. It includes functions for date validation, calculations, conversions, and formatting operations.
Key Features
- Date validation and type checking
- Weekday and month operations with locale support
- Date arithmetic (adding/subtracting time units)
- Business day calculations
- Quarter and season operations
- Random date/time generation
- Date range operations and intervals
Dependencies
- datetime: Core date/time functionality
- calendar: Calendar-related operations
- locale: Internationalization support
- zoneinfo: Timezone support (Python 3.9+)
Example
from datetime import datetime from date_operations import is_valid_date, add_time_to_date is_valid_date("2025-01-15") True add_time_to_date(datetime(2025, 1, 15), 30, 'days') datetime.datetime(2025, 2, 14, 0, 0)
Functions¶
academic_year(d: date, start_month: int = 9) -> str
¶
Returns the academic year label for a date.
An academic year that starts in September 2023 runs until
August 2024 and is labelled '2023/2024'.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
date
|
A |
required |
start_month
|
int
|
Month the academic year begins (default 9). |
9
|
Returns:
| Type | Description |
|---|---|
str
|
String in the form |
Raises:
| Type | Description |
|---|---|
TypeError
|
If d is not a date/datetime. |
Example
from datetime import date academic_year(date(2024, 2, 1)) '2023/2024'
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
add_days_from_now(days: int) -> datetime
¶
Adds or subtracts a specified number of days from the current date and time.
This function is a convenience wrapper around add_days_from_now, providing
a straightforward way to get a date offset from the present moment. It's
useful for scenarios where calculations always begin relative to "today"
or "now", such as setting deadlines, future reminders, or looking at past events.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
days
|
int
|
The number of days to add (positive) or subtract (negative). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
A new datetime object representing the date and time after adding/subtracting the specified number of days from the current time. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'days' is not an integer. (This check is implicitly handled
by the call to |
Example
from datetime import datetime
Get today's date (will vary based on when you run it)¶
today_plus_5_days = add_days_from_now(5) print(f"5 days from now: {today_plus_5_days}")
Expected output (will vary): 5 days from now: 2025-06-17 10:35:03.123456¶
yesterday = add_days_from_now(-1) print(f"Yesterday: {yesterday}")
Expected output (will vary): Yesterday: 2025-06-11 10:35:03.123456¶
future_date = add_days_from_now(30) print(f"30 days from now: {future_date}")
Expected output (will vary): 30 days from now: 2025-07-12 10:35:03.123456¶
Cost: O(1), constant time for getting current time and adding days.
Source code in shortfx/fxDate/date_operations.py
add_microseconds(date_input: datetime, microseconds: int) -> datetime
¶
Añade o resta un número específico de microsegundos a un objeto datetime.
Problema/Necesidad del Usuario: Para aplicaciones que requieren una precisión extremadamente alta en el tiempo (ej. trading financiero, mediciones científicas, sistemas de control), la capacidad de sumar o restar microsegundos es esencial.
Objetivos del Producto: Proporcionar una manipulación de tiempo con la granularidad más fina disponible en Python, abordando casos de uso de alta precisión.
Descripción: Esta función toma un objeto datetime y un entero que representa
la cantidad de microsegundos a añadir o restar. Los microsegundos pueden ser
positivos (para sumar) o negativos (para restar). La función devuelve un
nuevo objeto datetime con el ajuste aplicado.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
El objeto |
required |
microseconds
|
int
|
El número de microsegundos a añadir (positivo) o restar (negativo). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
Un nuevo objeto |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'date_input' no es un objeto |
Example
from datetime import datetime
Ejemplo 1: Sumar microsegundos¶
dt = datetime(2025, 6, 11, 10, 0, 0, 100) add_microseconds(dt, 50) datetime.datetime(2025, 6, 11, 10, 0, 0, 150)
Ejemplo 2: Restar microsegundos¶
dt = datetime(2025, 6, 11, 10, 0, 0, 500) add_microseconds(dt, -200) datetime.datetime(2025, 6, 11, 10, 0, 0, 300)
Ejemplo 3: Ajuste que afecta segundos (o componentes superiores)¶
dt = datetime(2025, 6, 11, 10, 0, 0, 999999) # Casi un segundo completo add_microseconds(dt, 2) datetime.datetime(2025, 6, 11, 10, 0, 1, 1) # Pasa al siguiente segundo y microsegundo 1
Ejemplo 4: Resta que afecta segundos (o componentes superiores)¶
dt = datetime(2025, 6, 11, 10, 0, 1, 5) # Un segundo y 5 microsegundos add_microseconds(dt, -10) datetime.datetime(2025, 6, 11, 9, 59, 59, 999995) # Retrocede un segundo, un minuto, etc.
Source code in shortfx/fxDate/date_operations.py
add_months(date_input: datetime, months: int) -> datetime
¶
Shifts a date forward or backward by a given number of months.
Description
Preserves the day-of-month when possible. If the target month has fewer days than the original day (e.g. Jan 31 + 1 month), clamps to the last day of the target month.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The starting date. |
required |
months
|
int
|
Number of months to add (positive) or subtract (negative). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
The resulting date with time components preserved. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If date_input is not a datetime or months is not an int. |
Example
from datetime import datetime add_months(datetime(2025, 1, 31), 1) datetime.datetime(2025, 2, 28, 0, 0) add_months(datetime(2025, 3, 15), -1) datetime.datetime(2025, 2, 15, 0, 0)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
add_time_to_date(original_date: datetime | str | date, quantity: int, unit: str) -> datetime
¶
Adds or subtracts a specified quantity of a given time unit to/from a date.
Description
This function takes a date, which can be a datetime object, a date object,
or a str, and adds or subtracts a specified quantity based on the unit.
It leverages the string_to_date helper function to intelligently parse string inputs.
If a date object is provided, it's converted to a datetime object at
the beginning of the day (00:00:00) to ensure consistent calculations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
original_date
|
datetime | str | date
|
The starting date. This can be a
|
required |
quantity
|
int
|
The number of units to add (positive) or subtract (negative). |
required |
unit
|
str
|
The unit of time to add or subtract. Valid units are: 'microseconds', 'milliseconds', 'seconds', 'minutes', 'hours', 'days', 'weeks'. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
A new |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'quantity' is not an integer or 'unit' is not a string. |
ValueError
|
If 'original_date' is a string that cannot be parsed by
|
Example of use
from datetime import datetime, date add_time_to_date(datetime(2023, 1, 15), 10, 'days') datetime.datetime(2023, 1, 25, 0, 0) add_time_to_date(date(2023, 1, 15), -5, 'days') datetime.datetime(2023, 1, 10, 0, 0) add_time_to_date("2023-01-15", 7, 'days') datetime.datetime(2023, 1, 22, 0, 0) add_time_to_date("2023/01/15 14:30:00", 2, 'hours') datetime.datetime(2023, 1, 15, 16, 30) add_time_to_date("2023-01-15 10:00:00", 30, 'minutes') datetime.datetime(2023, 1, 15, 10, 30) add_time_to_date("2023-01-15", 1, 'weeks') datetime.datetime(2023, 1, 22, 0, 0)
Cost: O(1)
Source code in shortfx/fxDate/date_operations.py
879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 | |
add_years(date_input: datetime, years: int) -> datetime
¶
Shifts a date forward or backward by a given number of years.
Description
Preserves the month and day when possible. If the original date is Feb 29 and the target year is not a leap year, clamps to Feb 28.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The starting datetime. |
required |
years
|
int
|
Number of years to add (positive) or subtract (negative). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
The resulting date with time components preserved. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If date_input is not a datetime or years is not an int. |
Example
add_years(datetime(2024, 2, 29, 10, 30), 1) datetime.datetime(2025, 2, 28, 10, 30) add_years(datetime(2025, 6, 15), -3) datetime.datetime(2022, 6, 15, 0, 0)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
age(birthdate: Union[str, date, datetime]) -> int
¶
Calculates the age in complete years from a birth date to today.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
birthdate
|
Union[str, date, datetime]
|
A date, datetime, or parseable date string. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The number of complete years elapsed. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If birthdate cannot be interpreted as a date. |
ValueError
|
If birthdate is in the future. |
Example
from datetime import date age(date(2000, 1, 1)) # assuming today is 2026-04-04 26
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
business_days_until(start: date | datetime, end: date | datetime, holidays: list | None = None) -> int
¶
Count working days between two dates, excluding weekends and holidays.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
date | datetime
|
Start date (inclusive). |
required |
end
|
date | datetime
|
End date (exclusive). |
required |
holidays
|
list | None
|
Optional list of |
None
|
Returns:
| Type | Description |
|---|---|
int
|
Number of business days. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If start or end are not date/datetime. |
Example
from datetime import date business_days_until(date(2026, 4, 6), date(2026, 4, 13)) 5
Complexity: O(d), d = days between start and end.
Source code in shortfx/fxDate/date_operations.py
business_hours_between(start_dt: datetime, end_dt: datetime, work_start: time = time(9, 0), work_end: time = time(17, 0)) -> float
¶
Calculates the number of business hours between two datetimes.
Counts only Mon--Fri hours within the [work_start, work_end) window.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_dt
|
datetime
|
Start datetime. |
required |
end_dt
|
datetime
|
End datetime. |
required |
work_start
|
time
|
Daily work-start time (default 09:00). |
time(9, 0)
|
work_end
|
time
|
Daily work-end time (default 17:00). |
time(17, 0)
|
Returns:
| Type | Description |
|---|---|
float
|
Total business hours as a float. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If start_dt > end_dt or work_start >= work_end. |
Example
business_hours_between( ... datetime(2026, 4, 6, 10, 0), ... datetime(2026, 4, 6, 15, 30)) 5.5
Complexity: O(d) where d is the number of calendar days spanned.
Source code in shortfx/fxDate/date_operations.py
business_quarter_label(d: date) -> str
¶
Returns a business quarter label for a date.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
date
|
A |
required |
Returns:
| Type | Description |
|---|---|
str
|
String in the form |
Raises:
| Type | Description |
|---|---|
TypeError
|
If d is not a date/datetime. |
Example
from datetime import date business_quarter_label(date(2024, 3, 15)) 'Q1 2024'
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
calculate_days_between_dates(start_date: datetime.date, end_date: datetime.date) -> int
¶
Calculates the number of days between two dates.
This function takes two date objects and returns the absolute difference in days between them. The order of the dates does not matter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
date
|
The first date. |
required |
end_date
|
date
|
The second date. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The number of days between the two dates. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If either start_date or end_date are not datetime.date objects. |
Example of use
from datetime import date date1 = date(2023, 1, 1) date2 = date(2023, 1, 31) calculate_days_between_dates(date1, date2) 30
Cost: O(1), constant time for date arithmetic.
Source code in shortfx/fxDate/date_operations.py
clamp_date(d, min_date, max_date)
¶
Clamp a date to the range [min_date, max_date].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
Date to clamp. |
required | |
min_date
|
Lower bound. |
required | |
max_date
|
Upper bound. |
required |
Returns:
| Type | Description |
|---|---|
|
Clamped date. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If arguments are not date/datetime. |
Example
from datetime import date clamp_date(date(2024, 6, 15), date(2024, 1, 1), date(2024, 3, 31)) datetime.date(2024, 3, 31)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
countdown_days(target: Union[datetime, date], from_date: Union[datetime, date, None] = None) -> int
¶
Counts the number of days until a target date.
Positive means target is in the future; negative means it is in the past.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
Union[datetime, date]
|
The target date. |
required |
from_date
|
Union[datetime, date, None]
|
The start date (defaults to today). |
None
|
Returns:
| Type | Description |
|---|---|
int
|
Number of days between from_date and target. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If inputs are not datetime or date objects. |
Example
from datetime import date countdown_days(date(2026, 12, 31), date(2026, 1, 1)) 364
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
cron_next_run(cron_expr: str, from_dt: Union[datetime, None] = None) -> datetime
¶
Returns the next datetime that matches a 5-field cron expression.
Fields: minute hour day month weekday (standard POSIX cron,
weekday 0=Sunday or 0=Monday both accepted via mod-7).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cron_expr
|
str
|
Five space-separated cron fields. |
required |
from_dt
|
Union[datetime, None]
|
Reference datetime (defaults to now). |
None
|
Returns:
| Type | Description |
|---|---|
datetime
|
The next matching datetime (seconds/microseconds zeroed). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If cron_expr is not a string. |
ValueError
|
If cron_expr does not have exactly 5 fields. |
Example
from datetime import datetime cron_next_run("0 9 * * *", datetime(2026, 4, 8, 10, 0)) datetime.datetime(2026, 4, 9, 9, 0)
Complexity: O(k) where k is minutes until next match (bounded by ~1 year)
Source code in shortfx/fxDate/date_operations.py
cron_previous_run(cron_expr: str, from_dt: Union[datetime, None] = None) -> datetime
¶
Returns the most recent past datetime matching a 5-field cron expression.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cron_expr
|
str
|
Five space-separated cron fields. |
required |
from_dt
|
Union[datetime, None]
|
Reference datetime (defaults to now). |
None
|
Returns:
| Type | Description |
|---|---|
datetime
|
The most recent past matching datetime. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If cron_expr is not a string. |
ValueError
|
If cron_expr does not have exactly 5 fields. |
Example
from datetime import datetime cron_previous_run("0 9 * * *", datetime(2026, 4, 8, 10, 0)) datetime.datetime(2026, 4, 8, 9, 0)
Complexity: O(k) where k is minutes since last match
Source code in shortfx/fxDate/date_operations.py
date_intervals(start_date: Union[datetime, str], end_date: Union[datetime, str], granularity: str, input_format: Optional[str] = None) -> List[Tuple[datetime, datetime]]
¶
Genera una lista de intervalos de fechas (inicio, fin) para una granularidad específica, alineados a las unidades naturales de la granularidad y cubriendo el rango dado.
Problema/Necesidad del Usuario: Es necesario segmentar un período de tiempo extenso en intervalos más pequeños y uniformes (años, trimestres, meses, etc.) para análisis, informes o procesamiento por lotes.
Objetivos del Producto: Proporcionar una herramienta flexible y precisa para dividir rangos de fechas en unidades de tiempo estandarizadas, facilitando la agregación y visualización de datos temporales.
Descripción: Esta función toma una fecha de inicio y una fecha de fin, junto
con una granularidad deseada, y devuelve una lista de tuplas,
donde cada tupla representa el (inicio, fin) de un intervalo. Los intervalos
se generan alineados a los inicios y fines naturales de su unidad (ej. 1 de mes,
lunes de semana) y cubren todas las unidades que intersectan
el rango [start_date, end_date].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
Union[datetime, str]
|
La fecha de inicio del rango (inclusiva). Puede ser un
objeto |
required |
end_date
|
Union[datetime, str]
|
La fecha de fin del rango (inclusiva). Puede ser un
objeto |
required |
granularity
|
str
|
La unidad de tiempo para los intervalos. Valores permitidos (en minúsculas): 'year', 'quarter', 'month', 'half_month', 'week', 'day', 'hour', 'minute', 'second'. |
required |
input_format
|
str
|
El formato de cadena de fecha (ej. '%Y-%m-%d %H:%M:%S') si 'start_date' o 'end_date' son cadenas. Es obligatorio si alguna de las fechas es una cadena. |
None
|
Returns:
| Type | Description |
|---|---|
List[Tuple[datetime, datetime]]
|
List[Tuple[datetime, datetime]]: Una lista de tuplas, donde cada tupla contiene (datetime_inicio_intervalo, datetime_fin_intervalo). Los objetos datetime de fin de intervalo siempre se ajustarán al final de la unidad de tiempo correspondiente (ej. 23:59:59.999999 para día). |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'start_date' o 'end_date' no son objetos datetime o cadenas. |
ValueError
|
Si 'input_format' es |
Example
from datetime import datetime, timedelta
1. Intervalos diarios¶
Cubre del 1 de junio al 3 de junio.¶
intervals_day = date_intervals(datetime(2025, 6, 1, 10, 0), datetime(2025, 6, 3, 14, 30), 'day') for s, e in intervals_day: print(f"({s}, {e})")
(2025-06-01 00:00:00, 2025-06-01 23:59:59.999999)¶
(2025-06-02 00:00:00, 2025-06-02 23:59:59.999999)¶
(2025-06-03 00:00:00, 2025-06-03 23:59:59.999999)¶
2. Intervalos semanales (Lunes como inicio de semana)¶
June 2025: 1st is Sunday. Week starts May 26.¶
Cubre desde la semana del 1 de junio hasta la semana del 9 de junio.¶
intervals_week = date_intervals(datetime(2025, 6, 1, 12, 0), datetime(2025, 6, 9, 10, 0), 'week') for s, e in intervals_week: print(f"({s}, {e})")
(2025-05-26 00:00:00, 2025-06-01 23:59:59.999999) # Semana que contiene el 1 de junio¶
(2025-06-02 00:00:00, 2025-06-08 23:59:59.999999) # Semana que contiene el 2 de junio¶
(2025-06-09 00:00:00, 2025-06-15 23:59:59.999999) # Semana que contiene el 9 de junio (hasta el 15, aunque end_date sea antes)¶
3. Intervalos mensuales¶
Cubre de enero a marzo 2025.¶
intervals_month = date_intervals(datetime(2025, 1, 15), datetime(2025, 3, 10), 'month') for s, e in intervals_month: print(f"({s}, {e})")
(2025-01-01 00:00:00, 2025-01-31 23:59:59.999999)¶
(2025-02-01 00:00:00, 2025-02-28 23:59:59.999999)¶
(2025-03-01 00:00:00, 2025-03-31 23:59:59.999999)¶
4. Intervalos de quincena (1-15, 16-fin de mes)¶
Cubre desde la 2da quincena de junio hasta la 2da quincena de julio 2025.¶
intervals_half_month = date_intervals(datetime(2025, 6, 10), datetime(2025, 7, 20), 'half_month') for s, e in intervals_half_month: print(f"({s}, {e})")
(2025-06-01 00:00:00, 2025-06-15 23:59:59.999999) # La quincena que contiene el 10 de junio¶
(2025-06-16 00:00:00, 2025-06-30 23:59:59.999999)¶
(2025-07-01 00:00:00, 2025-07-15 23:59:59.999999)¶
(2025-07-16 00:00:00, 2025-07-31 23:59:59.999999) # La quincena que contiene el 20 de julio¶
5. Intervalos de horas¶
date_intervals(datetime(2025, 6, 1, 10, 30), datetime(2025, 6, 1, 12, 15), 'hour')
Output: [(2025-06-01 10:00:00, 2025-06-01 10:59:59.999999),¶
(2025-06-01 11:00:00, 2025-06-01 11:59:59.999999),¶
(2025-06-01 12:00:00, 2025-06-01 12:59:59.999999)]¶
Source code in shortfx/fxDate/date_operations.py
3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 | |
date_part(part: str, my_date: datetime | str | date, first_day_of_week: int = 0, first_week_of_year: int = 1) -> int
¶
Extrae una parte específica de una fecha y hora, similar a la función DatePart de VBA.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
part
|
str
|
La parte de la fecha a extraer. Las opciones son:
- 'd': Día del mes (1-31)
- 'y': Día del año (1-366)
- 'h': Hora (0-23)
- 'n': Minuto (0-59)
- 's': Segundo (0-59)
- 'm': Mes (1-12)
- 'yyyy': Año
- 'w': Día de la semana (1-7). Requiere |
required |
my_date
|
datetime | str | date
|
La fecha/hora de la que se extraerá la parte. Puede ser un objeto datetime, date o una cadena. |
required |
first_day_of_week
|
(int, opcional)
|
Define el primer día de la semana para 'w' y 'ww'. 0 = Lunes (predeterminado), 6 = Domingo. (Similar a vbMonday=2 en VBA, pero aquí adaptado a 0-6). |
0
|
first_week_of_year
|
(int, opcional)
|
Define cómo se determina la primera semana del año para 'ww'. 1 = La semana que contiene el 1 de enero (predeterminado). Esta implementación se enfoca en ISO week number (semana que contiene el primer jueves). |
1
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
El valor entero de la parte de la fecha solicitada. |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'my_date' no puede ser convertido a un objeto datetime o si 'part' no es una cadena. |
ValueError
|
Si la 'part' solicitada no es válida o si hay un problema con los argumentos. |
Ejemplos de uso
from datetime import datetime, date my_date_obj = datetime(2024, 10, 25, 15, 35, 45) date_part("d", my_date_obj) 25 date_part("y", my_date_obj) 299 date_part("h", my_date_obj) 15 date_part("n", my_date_obj) 35 date_part("s", my_date_obj) 45 date_part("m", my_date_obj) 10 date_part("yyyy", my_date_obj) 2024 date_part("w", my_date_obj, first_day_of_week=0) # Lunes como primer día (por defecto) 5 # Viernes date_part("ww", my_date_obj, first_day_of_week=0, first_week_of_year=1) # ISO week number 43 date_part("ww", "2023-01-01", first_day_of_week=0, first_week_of_year=1) # Ejemplo ISO, 2023-01-01 es domingo, semana 52 de 2022 52 date_part("ww", "2023-01-02", first_day_of_week=0, first_week_of_year=1) # Lunes, semana 1 de 2023 1
Cost: O(1), constant time for extracting date components.
Source code in shortfx/fxDate/date_operations.py
1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 | |
date_range(start: Union[datetime, str, date], end: Union[datetime, str, date], step: int = 1, unit: str = 'days') -> List[datetime]
¶
Generates a list of dates between start and end at regular intervals.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
Union[datetime, str, date]
|
Start date (inclusive). Accepts datetime, date, or ISO string. |
required |
end
|
Union[datetime, str, date]
|
End date (inclusive). Accepts datetime, date, or ISO string. |
required |
step
|
int
|
Number of unit between each generated date. Must be positive. |
1
|
unit
|
str
|
Time unit for the step. Supported: 'days', 'weeks', 'hours', 'minutes', 'seconds'. |
'days'
|
Returns:
| Type | Description |
|---|---|
List[datetime]
|
List of datetime objects from start up to (and including) end. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If inputs cannot be converted to datetime. |
ValueError
|
If step < 1 or unit is unsupported. |
Example
from datetime import datetime date_range(datetime(2025, 1, 1), datetime(2025, 1, 5)) [datetime.datetime(2025, 1, 1, 0, 0), datetime.datetime(2025, 1, 2, 0, 0), datetime.datetime(2025, 1, 3, 0, 0), datetime.datetime(2025, 1, 4, 0, 0), datetime.datetime(2025, 1, 5, 0, 0)] date_range("2025-01-01", "2025-01-10", step=3, unit='days') [datetime.datetime(2025, 1, 1, 0, 0), datetime.datetime(2025, 1, 4, 0, 0), datetime.datetime(2025, 1, 7, 0, 0), datetime.datetime(2025, 1, 10, 0, 0)]
Complexity: O(n) where n is the number of dates produced.
Source code in shortfx/fxDate/date_operations.py
5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 | |
date_sequence(start: Union[datetime, date], end: Union[datetime, date], step_days: int = 1) -> List[date]
¶
Generates a list of dates from start to end (inclusive).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
Union[datetime, date]
|
First date in the sequence. |
required |
end
|
Union[datetime, date]
|
Last date in the sequence (inclusive if reached by step). |
required |
step_days
|
int
|
Number of days between consecutive dates (default 1). |
1
|
Returns:
| Type | Description |
|---|---|
List[date]
|
A list of date objects. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If start/end are not dates or step_days is not int. |
ValueError
|
If step_days == 0 or step direction doesn't match date order. |
Example
from datetime import date date_sequence(date(2026, 1, 1), date(2026, 1, 5)) [datetime.date(2026, 1, 1), datetime.date(2026, 1, 2), datetime.date(2026, 1, 3), datetime.date(2026, 1, 4), datetime.date(2026, 1, 5)]
Complexity: O(n) where n is the number of dates generated.
Source code in shortfx/fxDate/date_operations.py
6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 | |
date_to_ordinal(d) -> int
¶
Return the proleptic Gregorian ordinal of a date.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
A |
required |
Returns:
| Type | Description |
|---|---|
int
|
Ordinal integer (1 = January 1 of year 1). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If d is not a date or datetime. |
Example
from datetime import date date_to_ordinal(date(2024, 1, 1)) 738886
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
date_to_week_label(d: date) -> str
¶
Returns an ISO week label for a date.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
date
|
A |
required |
Returns:
| Type | Description |
|---|---|
str
|
String in the form |
Raises:
| Type | Description |
|---|---|
TypeError
|
If d is not a date/datetime. |
Example
from datetime import date date_to_week_label(date(2024, 1, 8)) 'W02-2024'
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
datedif(start_date: Union[date, datetime], end_date: Union[date, datetime], unit: str) -> int
¶
Calculates the difference between two dates in specified units.
Description
Returns the difference measured in complete years ("Y"), months ("M"), days ("D"), months ignoring years ("YM"), days ignoring months and years ("MD"), or days ignoring years ("YD"). Equivalent to Excel DATEDIF.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
Union[date, datetime]
|
The earlier date. |
required |
end_date
|
Union[date, datetime]
|
The later date. |
required |
unit
|
str
|
One of "Y", "M", "D", "YM", "MD", "YD". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The difference in the requested unit. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If dates are not date/datetime objects. |
ValueError
|
If start_date > end_date or unit is invalid. |
Example
from datetime import date datedif(date(2020, 3, 15), date(2025, 7, 20), "Y") 5 datedif(date(2020, 3, 15), date(2025, 7, 20), "M") 64 datedif(date(2020, 3, 15), date(2025, 7, 20), "D") 1953
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 | |
dates_between(start_date: datetime.date, end_date: datetime.date) -> list[datetime.date]
¶
Generates a list of dates between a start date and an end date, inclusive.
This function iterates day by day from the start_date up to and including the end_date, collecting each date into a list. The order of the input dates does not matter; the function will automatically determine the chronological start and end.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
date
|
The initial date. |
required |
end_date
|
date
|
The final date. |
required |
Returns:
| Type | Description |
|---|---|
list[date]
|
list[datetime.date]: A list containing all dates between the start and end dates. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If start_date or end_date are not datetime.date objects. |
Example of use
from datetime import date start = date(2023, 1, 1) end = date(2023, 1, 5) dates_between(start, end) [datetime.date(2023, 1, 1), datetime.date(2023, 1, 2), datetime.date(2023, 1, 3), datetime.date(2023, 1, 4), datetime.date(2023, 1, 5)]
start = date(2023, 1, 5) end = date(2023, 1, 1) dates_between(start, end) [datetime.date(2023, 1, 1), datetime.date(2023, 1, 2), datetime.date(2023, 1, 3), datetime.date(2023, 1, 4), datetime.date(2023, 1, 5)]
Source code in shortfx/fxDate/date_operations.py
day_of_year(d: Union[datetime, date]) -> int
¶
Returns the ordinal day of the year (1–366).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
Union[datetime, date]
|
A date or datetime. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The day number within the year. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If d is not a date or datetime. |
Example
from datetime import date day_of_year(date(2024, 3, 1)) 61
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
daylight_hours(latitude: float, d: Union[date, datetime]) -> float
¶
Estimates hours of daylight for a given latitude and date.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
latitude
|
float
|
Latitude in decimal degrees (positive North). |
required |
d
|
Union[date, datetime]
|
The date for calculation. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Approximate hours of daylight. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If inputs have wrong types. |
ValueError
|
If latitude is out of range. |
Example
round(daylight_hours(40.4168, date(2026, 6, 21)), 1) # Madrid summer 15.1
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
days_360(start_date: datetime, end_date: datetime, method: str = 'us') -> int
¶
Calculates days between two dates based on a 360-day year (12 months of 30 days).
Description
Commonly used in financial calculations (bond pricing, interest accrual). Two methods are supported: US (NASD) and European.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime
|
The start date. |
required |
end_date
|
datetime
|
The end date. |
required |
method
|
str
|
Calculation method — 'us' for US/NASD or 'eu' for European. Defaults to 'us'. |
'us'
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Number of days based on the 360-day year convention. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If start_date or end_date are not datetime objects. |
ValueError
|
If method is not 'us' or 'eu'. |
Example
from datetime import datetime days_360(datetime(2025, 1, 30), datetime(2025, 2, 28)) 28 days_360(datetime(2025, 1, 1), datetime(2025, 7, 1)) 180
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
days_between(start_date: datetime, end_date: datetime, basis: int = 0) -> int
¶
Calculates days between two dates based on a day-count basis.
Provides a single implementation for the five standard day-count conventions used in financial calculations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime
|
The start date. |
required |
end_date
|
datetime
|
The end date. |
required |
basis
|
int
|
Day-count convention: 0 — 30/360 US (NASD). 1 — Actual/Actual. 2 — Actual/360. 3 — Actual/365. 4 — 30/360 European. |
0
|
Returns:
| Type | Description |
|---|---|
int
|
Number of days according to the chosen basis. |
Example
from datetime import datetime days_between(datetime(2025, 1, 1), datetime(2025, 7, 1), basis=0) 180
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
days_in_month(year: int, month: int) -> int
¶
Returns the number of days in a given month and year.
Problem/User Need: When building calendars or validating date ranges (e.g., user input in a date form), it's crucial to know how many days a specific month has, as it varies (28, 29, 30, 31).
Product Goals: Provide a robust utility for validation and building calendar UIs, avoiding errors like "February 31st".
Description: Given a year and a month (as integers), this function returns the total number of days in that specific month, correctly handling leap years for February.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
The year (e.g., 2023, 2024). |
required |
month
|
int
|
The month (1 for January, 12 for December). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The number of days in the specified month of the given year. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'year' or 'month' are not integers. |
ValueError
|
If 'month' is not between 1 and 12, or if 'year' is less than 1. |
Example
days_in_month(2023, 2) # February 2023 (not a leap year) 28 days_in_month(2024, 2) # February 2024 (a leap year) 29 days_in_month(2023, 1) # January 31 days_in_month(2023, 4) # April 30
Cost: O(1), constant time for calendar lookup.
Source code in shortfx/fxDate/date_operations.py
days_remaining_in_year(d: Union[datetime, date]) -> int
¶
Returns the number of days remaining until 31 December.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
Union[datetime, date]
|
A date or datetime. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Days remaining in the year (0 on Dec 31). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If d is not a date or datetime. |
Example
from datetime import date days_remaining_in_year(date(2024, 12, 30)) 1
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
decimal_hours_between(dt1: Union[datetime, date], dt2: Union[datetime, date]) -> float
¶
Returns the decimal number of hours between two datetimes.
If plain date objects are given they are treated as midnight.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt1
|
Union[datetime, date]
|
Start datetime. |
required |
dt2
|
Union[datetime, date]
|
End datetime. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Decimal hours (positive when dt2 > dt1, negative otherwise). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If arguments are not datetime or date. |
Example
from datetime import datetime decimal_hours_between( ... datetime(2024, 1, 1, 8, 0), ... datetime(2024, 1, 1, 9, 30), ... ) 1.5
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
diff_time(start_date: datetime | str | date, end_date: datetime | str | date, unit: str) -> int
¶
Returns the whole-unit difference between two dates.
Description
Uses time_difference() to compute the delta and returns the integer
number of complete units between start_date and end_date. Supported
units mirror add_time_to_date: 'microseconds', 'milliseconds', 'seconds',
'minutes', 'hours', 'days', 'weeks'.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime | str | date
|
Start date/time. |
required |
end_date
|
datetime | str | date
|
End date/time. |
required |
unit
|
str
|
Unit of time ('microseconds', 'milliseconds', 'seconds', 'minutes', 'hours', 'days', 'weeks'). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Whole-unit difference according to the specified unit. |
Usage Example
from shortfx.fxDate.date_operations import diff_time diff_time("2025-01-01", "2025-01-03", "days") 2 diff_time("2025-01-01 00:00:00", "2025-01-02 12:00:00", "hours") 36 diff_time("2025-01-01", "2025-01-15", "weeks") 2
Notes
- This function returns whole units (integer truncation). For fractional
differences (e.g., 1.5 hours), use
time_difference()instead.
Cost: O(1)
Source code in shortfx/fxDate/date_operations.py
easter_date(year: int) -> date
¶
Computes the date of Easter Sunday for a given year.
Uses the Anonymous Gregorian algorithm (Meeus/Jones/Butcher) which is valid for years in the Gregorian calendar.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
The calendar year (e.g. 2025). |
required |
Returns:
| Type | Description |
|---|---|
date
|
A |
Raises:
| Type | Description |
|---|---|
TypeError
|
If year is not an integer. |
ValueError
|
If year < 1. |
Example
easter_date(2025) datetime.date(2025, 4, 20) easter_date(2024) datetime.date(2024, 3, 31) easter_date(2000) datetime.date(2000, 4, 23)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
elapsed_business_days(start: Union[datetime, date], end: Union[datetime, date], holidays: Optional[List[Union[datetime, date]]] = None) -> int
¶
Counts business days (Mon–Fri) between two dates, excluding holidays.
Both start and end are included when counting.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
Union[datetime, date]
|
Start date (inclusive). |
required |
end
|
Union[datetime, date]
|
End date (inclusive). |
required |
holidays
|
Optional[List[Union[datetime, date]]]
|
Optional list of holiday dates to exclude. |
None
|
Returns:
| Type | Description |
|---|---|
int
|
Number of business days. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If dates are not datetime or date objects. |
Example
from datetime import date elapsed_business_days(date(2024, 1, 1), date(2024, 1, 5)) 5
Complexity: O(n) where n is number of days in range
Source code in shortfx/fxDate/date_operations.py
6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 | |
end_of_month(date_input: Union[datetime, str], input_format: str = None) -> datetime
¶
Returns a datetime object representing the last day of the month for a given date.
Problem/User Need: Essential for closing monthly periods, defining complete date ranges, or calculating durations that span full months.
Product Goals: Complete the support for monthly reports and analysis, providing precise end-of-month boundaries.
Description: Given a date (as a datetime object or a string with a specified format), this function returns a new datetime object set to the last day of that date's month, at 23:59:59.999999. It correctly handles months with 28, 29, 30, or 31 days, including leap years.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Union[datetime, str]
|
The date for which to get the end of the month. Can be a datetime object (e.g., datetime(2023, 10, 15)) or a string (e.g., "15/10/2023"). |
required |
input_format
|
str
|
The format code string for 'date_input' if it's a string. Required if 'date_input' is a string. E.g., '%d/%m/%Y' for "15/10/2023". Not used if 'date_input' is a datetime object. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
A new datetime object representing the last day of the month, at 23:59:59.999999. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'date_input' is not a datetime object or a string. |
ValueError
|
If 'date_input' is a string and 'input_format' is not provided, or if the string cannot be parsed with the given format. |
Example
from datetime import datetime
Using a datetime object (October has 31 days)¶
end_of_month(datetime(2023, 10, 15, 10, 30, 0)) datetime.datetime(2023, 10, 31, 23, 59, 59, 999999)
Using a string input (February 2024 - a leap year)¶
end_of_month("20-02-2024", "%d-%m-%Y") datetime.datetime(2024, 2, 29, 23, 59, 59, 999999)
February 2023 (not a leap year)¶
end_of_month(datetime(2023, 2, 1)) datetime.datetime(2023, 2, 28, 23, 59, 59, 999999)
Cost: O(1), constant time for date manipulation and calendar lookup.
Source code in shortfx/fxDate/date_operations.py
2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 | |
end_of_month_offset(date_input: datetime, months: int) -> datetime
¶
Returns the last day of the month that is N months from date_input.
Description
Useful for calculating payment due dates, contract expirations, or any scenario requiring the last calendar day of a future/past month.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The reference date. |
required |
months
|
int
|
Number of months to offset (positive = forward, negative = back). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
A datetime set to the last day of the target month at 23:59:59.999999. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If date_input is not a datetime or months is not an int. |
Example
from datetime import datetime end_of_month_offset(datetime(2025, 1, 15), 0) datetime.datetime(2025, 1, 31, 23, 59, 59, 999999) end_of_month_offset(datetime(2025, 1, 15), 1) datetime.datetime(2025, 2, 28, 23, 59, 59, 999999) end_of_month_offset(datetime(2024, 1, 15), 1) datetime.datetime(2024, 2, 29, 23, 59, 59, 999999)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
end_of_quarter(date_input: Union[datetime, str], input_format: Optional[str] = None) -> datetime
¶
Returns the last day of the quarter for a given date.
Description
Determines which quarter the date belongs to and returns the last day of that quarter at 23:59:59.999999.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Union[datetime, str]
|
The date for which to get the end of the quarter. |
required |
input_format
|
Optional[str]
|
Format string if date_input is a string. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
Last day of the quarter at 23:59:59.999999. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If date_input is not a datetime or string. |
ValueError
|
If date_input is a string and input_format is not provided. |
Example
from datetime import datetime end_of_quarter(datetime(2026, 8, 15)) datetime.datetime(2026, 9, 30, 23, 59, 59, 999999) end_of_quarter(datetime(2026, 1, 20)) datetime.datetime(2026, 3, 31, 23, 59, 59, 999999)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
end_of_year(date_input: Union[datetime, str], input_format: str = None) -> datetime
¶
Returns a datetime object representing the last day of the year for a given date.
Problem/User Need: To close annual periods and define complete date ranges.
Product Goals: Complete the support for annual reports and analysis.
Description: Given a date (as a datetime object or a string with a specified format), this function returns a new datetime object set to December 31st of the year to which that date belongs, at 23:59:59.999999.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Union[datetime, str]
|
The date for which to get the end of the year. Can be a datetime object (e.g., datetime(2023, 7, 20)) or a string (e.g., "20/07/2023"). |
required |
input_format
|
str
|
The format code string for 'date_input' if it's a string. Required if 'date_input' is a string. E.g., '%d/%m/%Y' for "20/07/2023". Not used if 'date_input' is a datetime object. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
A new datetime object representing December 31st of the year, at 23:59:59.999999. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'date_input' is not a datetime object or a string. |
ValueError
|
If 'date_input' is a string and 'input_format' is not provided, or if the string cannot be parsed with the given format. |
Example
from datetime import datetime
Using a datetime object¶
end_of_year(datetime(2023, 7, 20)) datetime.datetime(2023, 12, 31, 23, 59, 59, 999999)
Using a string input¶
end_of_year("01-01-2024", "%d-%m-%Y") datetime.datetime(2024, 12, 31, 23, 59, 59, 999999)
Cost: O(1), constant time for date manipulation.
Source code in shortfx/fxDate/date_operations.py
filter_dates_by_weekday(dates: List[datetime], weekday: int) -> List[datetime]
¶
Filtra una lista de fechas, devolviendo solo aquellas que caen en un día específico de la semana.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dates
|
List[datetime]
|
Una lista de objetos datetime. |
required |
weekday
|
int
|
El día de la semana a filtrar (0=Lunes, 6=Domingo). |
required |
Returns:
| Type | Description |
|---|---|
List[datetime]
|
List[datetime]: Una nueva lista que contiene solo las fechas que coinciden con el día de la semana especificado. |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'dates' no es una lista, si contiene elementos que no son datetime, o si 'weekday' no es un entero. |
ValueError
|
Si 'weekday' está fuera del rango válido (0-6). |
Example
from datetime import datetime
Definir algunas fechas¶
date_list = [ ... datetime(2025, 6, 9), # Lunes ... datetime(2025, 6, 10), # Martes ... datetime(2025, 6, 11), # Miércoles ... datetime(2025, 6, 12), # Jueves ... datetime(2025, 6, 16), # Lunes ... datetime(2025, 6, 17), # Martes ... datetime(2025, 6, 15), # Domingo ... ]
Filtrar fechas que caen en Lunes (0)¶
monday_dates = filter_dates_by_weekday(date_list, 0) print(monday_dates) [datetime.datetime(2025, 6, 9, 0, 0), datetime.datetime(2025, 6, 16, 0, 0)]
Filtrar fechas que caen en Martes (1)¶
tuesday_dates = filter_dates_by_weekday(date_list, 1) print(tuesday_dates) [datetime.datetime(2025, 6, 10, 0, 0), datetime.datetime(2025, 6, 17, 0, 0)]
Filtrar fechas que caen en Sábado (5) - ninguna en la lista¶
saturday_dates = filter_dates_by_weekday(date_list, 5) print(saturday_dates) []
Lista vacía como entrada¶
filter_dates_by_weekday([], 0) []
Tipo de dato incorrecto en la lista (levantará TypeError)¶
try: filter_dates_by_weekday([datetime(2025, 1, 1), "not a date"], 0) except TypeError as e: print(f"Error: {e}")
Salida esperada: Error: All elements in 'dates' must be datetime objects.¶
'weekday' fuera de rango (levantará ValueError)¶
try: filter_dates_by_weekday(date_list, 7) except ValueError as e: print(f"Error: {e}")
Salida esperada: Error: 'weekday' must be an integer between 0 (Monday) and 6 (Sunday).¶
Source code in shortfx/fxDate/date_operations.py
4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 | |
first_day_of_week(date_input: Union[datetime, str], week_start_day: int = 0) -> datetime
¶
Calculates the first day of the week for a given date, allowing customization of the week's starting day.
Problema/Necesidad del Usuario: Es necesario encontrar el primer día de la semana para una fecha dada, donde la definición de "primer día" puede variar (ej. Lunes o Domingo). Esto es común en calendarios, informes y agregación de datos.
Objetivos del Producto: Proporcionar una función flexible que permita al usuario especificar el día que se considera el inicio de la semana, facilitando cálculos y visualizaciones consistentes con diferentes convenciones.
Descripción: Dada una fecha y un día de inicio de semana (por defecto Lunes),
esta función devuelve un objeto datetime que representa el primer día de la
semana que contiene la fecha dada. El día de inicio de semana se especifica
como un entero (0=Lunes, 1=Martes, ..., 6=Domingo). La fecha devuelta tendrá
su componente de tiempo establecido a medianoche (00:00:00).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Union[datetime, str]
|
La fecha para la cual se desea encontrar
el primer día de la semana. Puede ser un
objeto |
required |
week_start_day
|
int
|
Un entero que representa el día que se considera el inicio de la semana (0=Lunes, 1=Martes, ..., 6=Domingo). Por defecto es 0 (Lunes). |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
Un objeto |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'date_input' no es un objeto |
ValueError
|
Si 'week_start_day' no está entre 0 y 6, o si la cadena de fecha no puede ser parseada. |
Example
from datetime import datetime
Ejemplo 1: Obtener el primer día de la semana (Lunes por defecto) para el 15 de junio de 2025 (Domingo)¶
first_day_of_week(datetime(2025, 6, 15)) datetime.datetime(2025, 6, 9, 0, 0) # El lunes de esa semana es el 9 de junio
Ejemplo 2: Obtener el primer día de la semana (Domingo) para el 15 de junio de 2025¶
first_day_of_week(datetime(2025, 6, 15), week_start_day=6) datetime.datetime(2025, 6, 15, 0, 0) # El domingo de esa semana es el 15 de junio
Ejemplo 3: Usando una cadena de fecha¶
first_day_of_week("2025-06-15", week_start_day=0) datetime.datetime(2025, 6, 9, 0, 0)
Ejemplo 4: Día de inicio de semana inválido (levantará ValueError)¶
try: first_day_of_week(datetime(2025, 6, 15), week_start_day=7) except ValueError as e: print(f"Error: {e}")
Expected output: Error: week_start_day must be between 0 (Monday) and 6 (Sunday).¶
Cost: O(1), constant time for date arithmetic operations.
Source code in shortfx/fxDate/date_operations.py
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | |
fiscal_quarter(d: Union[datetime, date], fiscal_start_month: int = 1) -> int
¶
Returns the fiscal quarter (1-4) for a given date.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
Union[datetime, date]
|
A datetime or date object. |
required |
fiscal_start_month
|
int
|
The month the fiscal year starts (1-12). Default 1 = calendar year. |
1
|
Returns:
| Type | Description |
|---|---|
int
|
An integer 1-4 representing the fiscal quarter. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If d is not a datetime/date or fiscal_start_month not int. |
ValueError
|
If fiscal_start_month not in 1-12. |
Example
from datetime import date fiscal_quarter(date(2026, 3, 15)) 1 fiscal_quarter(date(2026, 3, 15), fiscal_start_month=4) 4 fiscal_quarter(date(2026, 7, 1), fiscal_start_month=4) 2
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
format_date_iso(d) -> str
¶
Format a date or datetime as ISO 8601 string (YYYY-MM-DD).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
A |
required |
Returns:
| Type | Description |
|---|---|
str
|
ISO 8601 date string. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If d is not a date or datetime. |
Example
from datetime import date format_date_iso(date(2024, 3, 15)) '2024-03-15'
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
format_datetime_ampm(dt_object: datetime) -> str
¶
Formats a datetime object into a 12-hour (AM/PM) string representation.
This function takes a datetime object and converts it into a string formatted as 'YYYY-MM-DD HH:MM:SS AM/PM'. This is a common and clear way to display time with an AM/PM indicator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt_object
|
datetime
|
The datetime object to format. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
A string representing the datetime object in AM/PM format. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the input dt_object is not a datetime.datetime object. |
Example of use
from datetime import datetime now = datetime(2025, 6, 29, 15, 30, 0) format_datetime_ampm(now) '2025-06-29 03:30:00 PM'
morning = datetime(2025, 6, 29, 9, 15, 45) format_datetime_ampm(morning) '2025-06-29 09:15:45 AM'
Cost: O(1), constant time for string formatting.
Source code in shortfx/fxDate/date_operations.py
format_datetime_iso(dt) -> str
¶
Format a datetime as ISO 8601 string (YYYY-MM-DDTHH:MM:SS).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
A |
required |
Returns:
| Type | Description |
|---|---|
str
|
ISO 8601 datetime string. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If dt is not a datetime. |
Example
from datetime import datetime format_datetime_iso(datetime(2024, 3, 15, 10, 30, 0)) '2024-03-15T10:30:00'
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
full_months_between(start_date: datetime, end_date: datetime) -> int
¶
Devuelve el número de meses completos transcurridos entre start_date y end_date. No cuenta meses parciales.
Problema/Necesidad del Usuario: Similar al cálculo de años, pero para el número de meses completos. Útil para períodos de facturación, suscripciones o antigüedad laboral.
Objetivos del Producto: Ofrecer una función precisa para calcular la diferencia de meses completos, esencial para la gestión de membresías, finanzas o cualquier ciclo mensual.
Descripción: Esta función calcula el número de meses completos que han pasado desde start_date hasta end_date.
Un mes completo se cuenta solo si end_date ha alcanzado o superado el día de start_date en el mes end_date.
Si start_date es posterior a end_date, el resultado será un número negativo.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime
|
La fecha de inicio. |
required |
end_date
|
datetime
|
La fecha de fin. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
El número de meses completos transcurridos. |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si |
Example
from datetime import datetime
Ejemplo 1: Solo un mes completo (del 15 de enero al 14 de marzo)¶
full_months_between(datetime(2025, 1, 15), datetime(2025, 3, 14)) 1
Ejemplo 2: Dos meses completos (del 15 de enero al 15 de marzo)¶
full_months_between(datetime(2025, 1, 15), datetime(2025, 3, 15)) 2
Ejemplo 3: Múltiples meses completos¶
full_months_between(datetime(2024, 8, 1), datetime(2025, 2, 28)) 6
Ejemplo 4: Solo días, sin meses completos¶
full_months_between(datetime(2025, 1, 1), datetime(2025, 1, 31)) 0
Ejemplo 5: Fechas en orden invertido (resultado negativo)¶
full_months_between(datetime(2025, 3, 15), datetime(2025, 1, 15)) -2
Ejemplo 6: Con días que "no cumplen" el mes completo¶
full_months_between(datetime(2025, 1, 31), datetime(2025, 3, 1)) 1 # De 31 de enero a 1 de marzo, solo se ha completado febrero.
Source code in shortfx/fxDate/date_operations.py
4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 | |
full_years_between(start_date: datetime, end_date: datetime) -> int
¶
Devuelve el número de años completos transcurridos entre start_date y end_date. No cuenta años parciales.
Problema/Necesidad del Usuario: Calcular el número de años completos transcurridos entre dos fechas. Diferente de la resta simple que podría dar decimales. Esto es útil para cálculos de edad exactos o periodos de tiempo completos.
Objetivos del Producto: Proporcionar una función precisa para calcular la diferencia de años completos, que es vital en cálculos demográficos, contractuales o de antigüedad.
Descripción: Esta función calcula el número de años completos que han pasado desde start_date hasta end_date.
Un año completo se cuenta solo si end_date ha alcanzado o superado el día y mes de start_date en el año end_date.
Si start_date es posterior a end_date, el resultado será un número negativo.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime
|
La fecha de inicio. |
required |
end_date
|
datetime
|
La fecha de fin. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
El número de años completos transcurridos. |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si |
Example
from datetime import datetime
Ejemplo 1: No se ha completado el quinto año (falta 1 día)¶
full_years_between(datetime(2020, 6, 11), datetime(2025, 6, 10)) 4
Ejemplo 2: Se ha completado el quinto año (en el mismo día)¶
full_years_between(datetime(2020, 6, 11), datetime(2025, 6, 11)) 5
Ejemplo 3: Múltiples años completos¶
full_years_between(datetime(2010, 1, 1), datetime(2025, 12, 31)) 15
Ejemplo 4: Solo días, sin años completos¶
full_years_between(datetime(2025, 1, 1), datetime(2025, 12, 31)) 0
Ejemplo 5: Fechas en orden invertido (resultado negativo)¶
full_years_between(datetime(2025, 6, 11), datetime(2020, 6, 10)) -4
Ejemplo 6: Diferencia de días dentro del mismo año (sin años completos)¶
full_years_between(datetime(2025, 1, 15), datetime(2025, 3, 14)) 0
Source code in shortfx/fxDate/date_operations.py
4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 | |
generate_random_date(start_date: Optional[date] = None, end_date: Optional[date] = None, business_days_only: bool = False) -> date
¶
Generates a random date within a specified range, optionally restricted to business days.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
Optional[date]
|
The earliest possible date. Defaults to 1900-01-01 if None. |
None
|
end_date
|
Optional[date]
|
The latest possible date. Defaults to 2100-12-31 if None. |
None
|
business_days_only
|
bool
|
If True, only returns dates that are not Saturdays or Sundays. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
date |
date
|
A randomly generated date. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If start_date is after end_date. |
TypeError
|
If start_date or end_date are not date objects, or business_days_only is not a bool. |
Example
Get a random date today or in the future (up to 2050)¶
from datetime import date today = date.today() generate_random_date(start_date=today, end_date=date(2050, 12, 31))
Example output: date(2035, 7, 23)¶
Get a random date in the past, only on business days¶
generate_random_date(start_date=date(2020, 1, 1), end_date=date(2022, 12, 31), business_days_only=True)
Example output: date(2021, 5, 18) (not a Saturday/Sunday)¶
Get a random date with default range¶
generate_random_date()
Example output: date(2045, 11, 5)¶
Invalid date range (will raise ValueError)¶
try: generate_random_date(start_date=date(2025, 1, 1), end_date=date(2024, 1, 1)) except ValueError as e: print(f"Error: {e}")
Expected output: Error: start_date cannot be after end_date.¶
Source code in shortfx/fxDate/date_operations.py
4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 | |
generate_random_datetime(start_dt: Optional[datetime] = None, end_dt: Optional[datetime] = None, tz_info: Optional[str] = None) -> datetime
¶
Generates a random datetime object within a specified range, optionally localized to a timezone.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_dt
|
Optional[datetime]
|
The earliest possible datetime. Defaults to 1900-01-01 00:00:00 UTC if None. |
None
|
end_dt
|
Optional[datetime]
|
The latest possible datetime. Defaults to 2100-12-31 23:59:59.999999 UTC if None. |
None
|
tz_info
|
Optional[str]
|
IANA timezone string (e.g., 'America/New_York', 'Europe/Madrid'). If None, the generated datetime will be naive (without timezone info). If a timezone is provided, start_dt/end_dt are converted to it for range calculation or assumed to be in that timezone if naive. It's best to provide timezone-aware datetimes. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
A randomly generated datetime. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If start_dt is after end_dt, or if tz_info is an invalid timezone string. |
TypeError
|
If start_dt or end_dt are not datetime objects, or tz_info is not a string. |
ZoneInfoNotFoundError
|
(Captured and re-raised as ValueError) If the timezone is not found. |
Example
Get a random datetime in the next year (UTC)¶
from datetime import datetime, timezone now = datetime.now(timezone.utc) generate_random_datetime(start_dt=now, end_dt=now + timedelta(days=365), tz_info='UTC')
Example output: datetime.datetime(2026, 3, 10, 15, 30, 45, 123456, tzinfo=datetime.timezone.utc)¶
Get a random datetime in a specific timezone (e.g., Madrid) for a past month¶
generate_random_datetime(start_dt=datetime(2025, 5, 1, 0, 0, 0), end_dt=datetime(2025, 5, 31, 23, 59, 59), tz_info='Europe/Madrid')
Example output: datetime.datetime(2025, 5, 18, 11, 7, 22, 98765, tzinfo=zoneinfo.ZoneInfo(key='Europe/Madrid'))¶
Get a random naive datetime (no timezone)¶
generate_random_datetime(start_dt=datetime(2020, 1, 1), end_dt=datetime(2020, 12, 31))
Example output: datetime.datetime(2020, 7, 10, 8, 55, 1, 54321)¶
Invalid datetime range (will raise ValueError)¶
try: generate_random_datetime(start_dt=datetime(2025, 1, 1), end_dt=datetime(2024, 1, 1)) except ValueError as e: print(f"Error: {e}")
Expected output: Error: start_dt cannot be after end_dt.¶
Source code in shortfx/fxDate/date_operations.py
4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 | |
generate_random_time(min_time: Optional[time] = None, max_time: Optional[time] = None) -> time
¶
Generates a random time object within an optional specified range.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_time
|
Optional[time]
|
The earliest possible time. Defaults to 00:00:00 if None. |
None
|
max_time
|
Optional[time]
|
The latest possible time. Defaults to 23:59:59.999999 if None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
time |
time
|
A randomly generated time. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If min_time is after max_time. |
TypeError
|
If min_time or max_time are not time objects. |
Example
Get a random time between 9 AM and 5 PM¶
generate_random_time(min_time=time(9, 0, 0), max_time=time(17, 0, 0))
Example output: datetime.time(14, 23, 5, 876543)¶
Get a random time with default range (any time of day)¶
generate_random_time()
Example output: datetime.time(21, 5, 34, 123456)¶
Invalid time range (will raise ValueError)¶
try: generate_random_time(min_time=time(17, 0, 0), max_time=time(9, 0, 0)) except ValueError as e: print(f"Error: {e}")
Expected output: Error: min_time cannot be after max_time.¶
Source code in shortfx/fxDate/date_operations.py
get_age_from_dob(dob: Union[datetime, str], dob_format: str = None, as_of_date: Optional[datetime] = None) -> int
¶
Calculates the age in full years from a date of birth.
Problem/User Need: Calculating age is a very common operation in applications with user profiles, registration systems, or age requirements.
Product Goals: Simplify a common date calculation that often has nuances (e.g., past or future birthdays) and can be prone to errors if implemented manually.
Description: Given a date of birth (dob) and an optional reference date (defaults to the current date if not provided), this function calculates the age in complete years. It correctly handles cases where the birthday has not yet occurred in the reference year.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dob
|
Union[datetime, str]
|
The date of birth. Can be a datetime object or a string. |
required |
dob_format
|
str
|
The format code string for |
None
|
as_of_date
|
Optional[datetime]
|
The reference date to calculate the age against.
If |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The age in full years. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
ValueError
|
If |
Example
from datetime import datetime, timezone
Birthday on the same day as reference date¶
get_age_from_dob(datetime(1990, 6, 11), as_of_date=datetime(2025, 6, 11)) 35
Birthday has already passed in the reference year¶
get_age_from_dob(datetime(1990, 1, 15), as_of_date=datetime(2025, 6, 11)) 35
Birthday has NOT yet passed in the reference year¶
get_age_from_dob(datetime(1990, 12, 25), as_of_date=datetime(2025, 6, 11)) 34
Using current date as reference (assumes current date is 2025-06-11 UTC)¶
Actual result will vary based on current system date.¶
get_age_from_dob(datetime(1990, 6, 11)) 35
Using string input for date of birth¶
get_age_from_dob("1985-03-20", dob_format="%Y-%m-%d", as_of_date=datetime(2025, 6, 11)) 40
Date of birth in the future (will raise ValueError)¶
try: get_age_from_dob(datetime(2030, 1, 1), as_of_date=datetime(2025, 1, 1)) except ValueError as e: print(f"Error: {e}")
Expected output: Error: Date of birth cannot be in the future relative to the reference date.¶
Cost: O(1), constant time for date arithmetic and comparison.
Source code in shortfx/fxDate/date_operations.py
3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 | |
get_date_component(date_input: datetime, component: Literal['day', 'month', 'year', 'hour', 'minute', 'second']) -> int
¶
Extracts a specific component (day, month, year, hour, minute, or second) from a date.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The datetime object from which to extract the component. |
required |
component
|
Literal['day', 'month', 'year', 'hour', 'minute', 'second']
|
A string indicating which component to extract. Must be "day", "month", "year", "hour", "minute", or "second". |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The requested date component (day of month, month number, year number, hour number (0-23), minute number (0-59), or second number (0-59)). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'date_input' is not a datetime object. |
ValueError
|
If 'component' is not one of the allowed values. |
Example
from datetime import datetime my_date = datetime(2023, 10, 26, 15, 30, 45) # 3:30:45 PM get_date_component(my_date, "day") 26 get_date_component(my_date, "month") 10 get_date_component(my_date, "year") 2023 get_date_component(my_date, "hour") 15 get_date_component(my_date, "minute") 30 get_date_component(my_date, "second") 45
Cost: O(1), constant time for accessing datetime attributes.
Source code in shortfx/fxDate/date_operations.py
get_first_business_day_of_month(year: int, month: int, holidays: Optional[List[datetime]] = None) -> datetime
¶
Devuelve el primer día hábil de un mes y año dados, considerando fines de semana y una lista opcional de festivos.
Problema/Necesidad del Usuario: Muchas operaciones financieras, pagos o inicios de ciclo de informes se basan en el primer día hábil de un mes.
Objetivos del Producto: Proporcionar una función precisa para la planificación de recursos y la contabilidad de tiempo de trabajo, lo que es crucial en entornos empresariales.
Descripción: Esta función calcula y devuelve el primer día laborable (excluyendo sábados, domingos y una lista opcional de festivos) de un mes y año específicos. La fecha devuelta tendrá su componente de tiempo establecido a medianoche (00:00:00).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
El año para el cual se desea obtener el primer día hábil. |
required |
month
|
int
|
El mes (1-12) para el cual se desea obtener el primer día hábil. |
required |
holidays
|
Optional[List[datetime]]
|
Una lista opcional de objetos |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
Un objeto |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'year' o 'month' no son enteros, o si 'holidays' no es una lista de datetimes (o None). |
ValueError
|
Si 'year' está fuera del rango válido (1-9999), o si 'month' no está entre 1 y 12. |
Example
from datetime import datetime, date
Ejemplo 1: Enero 2025 (1 de enero es Miércoles)¶
get_first_business_day_of_month(2025, 1) datetime.datetime(2025, 1, 1, 0, 0) # El 1 de enero de 2025 es un Miércoles.
Ejemplo 2: Marzo 2025 (1 de marzo es Sábado)¶
get_first_business_day_of_month(2025, 3) datetime.datetime(2025, 3, 3, 0, 0) # El 1 y 2 de marzo son Sábado y Domingo. El 3 de marzo es Lunes.
Ejemplo 3: Diciembre 2025 (1 de diciembre es Lunes, pero si fuera festivo)¶
Asumiendo que el 1 y 2 de diciembre de 2025 son festivos.¶
custom_holidays = [datetime(2025, 12, 1), datetime(2025, 12, 2)] get_first_business_day_of_month(2025, 12, holidays=custom_holidays) datetime.datetime(2025, 12, 3, 0, 0) # El 1 y 2 de dic son festivos. El 3 de dic es Miércoles.
Mes inválido (levantará ValueError)¶
try: get_first_business_day_of_month(2025, 13) except ValueError as e: print(f"Error: {e}")
Expected output: Error: Month must be between 1 and 12.¶
Cost: O(1), constant time for finding first business day (typically requires checking only a few days).
Source code in shortfx/fxDate/date_operations.py
2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 | |
get_last_business_day_of_month(year: int, month: int, holidays: Optional[List[datetime]] = None) -> datetime
¶
Devuelve el último día hábil de un mes y año dados, considerando fines de semana y una lista opcional de festivos.
Problema/Necesidad del Usuario: Muchas operaciones financieras, cierres de período, o plazos de informes se basan en el último día hábil de un mes.
Descripción: Esta función calcula y devuelve el último día laborable (excluyendo sábados, domingos y una lista opcional de festivos) de un mes y año específicos. La fecha devuelta tendrá su componente de tiempo establecido a medianoche (00:00:00).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
El año para el cual se desea obtener el último día hábil. |
required |
month
|
int
|
El mes (1-12) para el cual se desea obtener el último día hábil. |
required |
holidays
|
Optional[List[datetime]]
|
Una lista opcional de objetos |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
Un objeto |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'year' o 'month' no son enteros, o si 'holidays' no es una lista de datetimes (o None). |
ValueError
|
Si 'year' está fuera del rango válido (1-9999), o si 'month' no está entre 1 y 12. |
Example
from datetime import datetime, date import calendar
Ejemplo 1: Junio 2025 (30 de junio es Lunes)¶
get_last_business_day_of_month(2025, 6) datetime.datetime(2025, 6, 30, 0, 0) # El 30 de junio de 2025 es un Lunes.
Ejemplo 2: Mayo 2025 (31 de mayo es Sábado)¶
get_last_business_day_of_month(2025, 5) datetime.datetime(2025, 5, 30, 0, 0) # El 31 de mayo es Sábado, el 30 de mayo es Viernes.
Ejemplo 3: Enero 2025 (31 de enero es Viernes, pero si fuera festivo)¶
Asumiendo que el 31 de enero de 2025 es un festivo.¶
custom_holidays = [datetime(2025, 1, 31)] get_last_business_day_of_month(2025, 1, holidays=custom_holidays) datetime.datetime(2025, 1, 30, 0, 0) # El 31 de enero es festivo, el 30 de enero es Jueves.
Mes inválido (levantará ValueError)¶
try: get_last_business_day_of_month(2025, 0) except ValueError as e: print(f"Error: {e}")
Expected output: Error: Month must be between 1 and 12.¶
Cost: O(1), constant time for finding last business day (typically requires checking only a few days).
Source code in shortfx/fxDate/date_operations.py
2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 | |
get_last_friday_of_month(year: int, month: int) -> datetime
¶
Calculates the date of the last Friday of a given month and year.
This function determines the last day of the specified month and then iterates backward to find the most recent Friday.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
The year (e.g., 2023). |
required |
month
|
int
|
The month (1-12, e.g., 10 for October). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
A datetime object representing the last Friday of that month, at midnight. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'year' or 'month' are not integers. |
ValueError
|
If 'month' is not between 1 and 12, or if 'year' is less than 1. |
Example
get_last_friday_of_month(2023, 10) # October 2023 datetime.datetime(2023, 10, 27, 0, 0) get_last_friday_of_month(2024, 2) # February 2024 (leap year) datetime.datetime(2024, 2, 23, 0, 0)
Cost: O(1), constant time for date calculation.
Source code in shortfx/fxDate/date_operations.py
get_next_friday(date_input: datetime) -> datetime
¶
Calculates the date of the next upcoming Friday relative to a given date.
This function is useful for scheduling or determining the immediate future occurrence of Friday.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The starting date from which to find the next Friday. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
A datetime object representing the next Friday, at midnight. If the input date is a Friday, it returns the Friday of the following week. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'date_input' is not a datetime object. |
Example
get_next_friday(datetime(2023, 10, 26)) # Thursday datetime.datetime(2023, 10, 27, 0, 0) get_next_friday(datetime(2023, 10, 27)) # Friday datetime.datetime(2023, 11, 3, 0, 0) get_next_friday(datetime(2023, 10, 28)) # Saturday datetime.datetime(2023, 11, 3, 0, 0)
Cost: O(1), constant time for date arithmetic.
Source code in shortfx/fxDate/date_operations.py
get_nth_weekday_of_month(year: int, month: int, weekday: int, n: int) -> Optional[datetime]
¶
Calculates the date of the n-th occurrence of a specific weekday in a given month.
Problema/Necesidad del Usuario: A veces, se necesita encontrar una fecha muy específica como "el tercer martes de cada mes" o "el primer lunes del trimestre". Esto es común en programaciones recurrentes o plazos específicos.
Objetivos del Producto: Proporcionar una función de cálculo de fechas recurrente que es sorprendentemente compleja de implementar manualmente y propensa a errores.
Descripción: Dada un año, un mes, un día de la semana (donde 0=Lunes, 6=Domingo)
y un número 'n' (por ejemplo, 1 para el primero, 2 para el segundo), esta función
devuelve la fecha de la n-ésima ocurrencia de ese día de la semana en el mes.
Si la n-ésima ocurrencia no existe dentro de ese mes (por ejemplo, pedir el quinto
viernes en un mes que solo tiene cuatro), devuelve None.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
El año (ej., 2025). |
required |
month
|
int
|
El mes (1-12, ej., 6 para junio). |
required |
weekday
|
int
|
El día de la semana (0=Lunes, 1=Martes, ..., 6=Domingo). |
required |
n
|
int
|
El número de ocurrencia (ej., 1 para la primera, 2 para la segunda, etc.). Debe ser un entero positivo. |
required |
Returns:
| Type | Description |
|---|---|
Optional[datetime]
|
Optional[datetime]: Un objeto |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'year', 'month', 'weekday' o 'n' no son enteros. |
ValueError
|
Si 'year' está fuera del rango válido (1-9999), 'month' no está entre 1-12, 'weekday' no está entre 0-6, o 'n' no es un entero positivo. |
Example
Obtener el segundo martes (weekday 1) de junio de 2025¶
get_nth_weekday_of_month(2025, 6, 1, 2) datetime.datetime(2025, 6, 10, 0, 0)
Obtener el primer lunes (weekday 0) de enero de 2024¶
get_nth_weekday_of_month(2024, 1, 0, 1) datetime.datetime(2024, 1, 1, 0, 0)
Obtener el último (cuarto) jueves (weekday 3) de febrero de 2024 (año bisiesto)¶
get_nth_weekday_of_month(2024, 2, 3, 4) datetime.datetime(2024, 2, 29, 0, 0)
Intentar obtener el quinto lunes de febrero de 2024 (no existe)¶
get_nth_weekday_of_month(2024, 2, 0, 5) None
Mes inválido (levantará ValueError)¶
try: get_nth_weekday_of_month(2025, 13, 0, 1) except ValueError as e: print(f"Error: {e}")
Expected output: Error: Month must be between 1 and 12.¶
Cost: O(1), constant time for date calculation.
Source code in shortfx/fxDate/date_operations.py
733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 | |
get_number_of_days_in_quarter(year: int, quarter: int) -> int
¶
Calculates the total number of days in a specific quarter of a given year.
Problema/Necesidad del Usuario: Para informes y análisis financieros o de rendimiento que se basan en trimestres, es necesario saber el número exacto de días en un trimestre dado, lo cual varía debido a la duración de los meses y los años bisiestos.
Objetivos del Producto: Facilitar cálculos precisos basados en periodos trimestrales, sin tener que codificar manualmente la lógica de los meses y los años bisiestos.
Descripción: Dada un año y un número de trimestre (1-4), esta función devuelve el número total de días en ese trimestre. Considera correctamente la duración de cada mes y el efecto de los años bisiestos en febrero.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
El año para el cual se desea calcular el número de días en el trimestre. |
required |
quarter
|
int
|
El número del trimestre (1, 2, 3 o 4). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
El número total de días en el trimestre especificado. |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'year' o 'quarter' no son enteros. |
ValueError
|
Si 'year' está fuera del rango válido (1-9999), o si 'quarter' no está entre 1 y 4. |
Example
get_number_of_days_in_quarter(2024, 1) # Q1 de un año bisiesto (Ene, Feb(29), Mar) 91 get_number_of_days_in_quarter(2023, 1) # Q1 de un año común (Ene, Feb(28), Mar) 90 get_number_of_days_in_quarter(2023, 2) # Q2 de un año común (Abr, May, Jun) 91 get_number_of_days_in_quarter(2023, 3) # Q3 de un año común (Jul, Ago, Sep) 92 get_number_of_days_in_quarter(2023, 4) # Q4 de un año común (Oct, Nov, Dic) 92
Año fuera de rango (levantará ValueError)¶
try: get_number_of_days_in_quarter(0, 1) except ValueError as e: print(f"Error: {e}")
Expected output: Error: Year is out of valid range (1-9999).¶
Cost: O(1), constant time for summing days in three months.
Source code in shortfx/fxDate/date_operations.py
2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 | |
get_number_of_days_in_year(year: int) -> int
¶
Calculates the total number of days in a given year.
Problem/User Need: There is a need to know the total number of days in a specific year for calculations like annual percentages, averages, or data validations.
Product Goals: Simplify annual calculations and ensure accuracy by correctly considering leap years, which have an extra day.
Description: Given a year as an integer, this function determines if it's a leap year. If it is (e.g., 2024, 2000), it returns 366 days. Otherwise (e.g., 2023, 1900), it returns 365 days.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
The year for which to get the number of days (e.g., 2023, 2024). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The total number of days in that year (either 365 or 366). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'year' is not an integer. |
ValueError
|
If 'year' is less than 1. |
Example
get_number_of_days_in_year(2023) # Not a leap year 365 get_number_of_days_in_year(2024) # A leap year 366 get_number_of_days_in_year(1900) # Not a leap year (divisible by 100 but not by 400) 365 get_number_of_days_in_year(2000) # A leap year (divisible by 400) 366
Cost: O(1), constant time for leap year check.
Source code in shortfx/fxDate/date_operations.py
get_previous_friday(date_input: datetime) -> datetime
¶
Calculates the date of the immediately preceding Friday relative to a given date.
This function is useful for going back in time to the nearest past Friday, for instance, to align data to the end of the last working week.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The starting date from which to find the previous Friday. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
A datetime object representing the previous Friday, at midnight. If the input date is a Friday, it returns that date itself. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'date_input' is not a datetime object. |
Example
from datetime import datetime
Starting from a Monday (June 9, 2025 was a Monday)¶
get_previous_friday(datetime(2025, 6, 9)) datetime.datetime(2025, 6, 6, 0, 0)
Starting from a Thursday (June 12, 2025 will be a Thursday)¶
get_previous_friday(datetime(2025, 6, 12)) datetime.datetime(2025, 6, 6, 0, 0)
Starting from a Friday (June 6, 2025 was a Friday)¶
get_previous_friday(datetime(2025, 6, 6)) datetime.datetime(2025, 6, 6, 0, 0)
Starting from a Sunday (June 8, 2025 was a Sunday)¶
get_previous_friday(datetime(2025, 6, 8)) datetime.datetime(2025, 6, 6, 0, 0)
Cost: O(1), constant time for date arithmetic.
Source code in shortfx/fxDate/date_operations.py
get_quarter(date_input: Union[datetime, str], input_format: Optional[str] = None) -> int
¶
Extrae el número de trimestre (1 a 4) al que pertenece una fecha dada.
Problema/Necesidad del Usuario: Extraer el trimestre de una fecha es una operación muy común para informes financieros, de ventas o de rendimiento que se agrupan por trimestres.
Objetivos del Producto: Proporcionar una forma sencilla y directa de obtener el trimestre al que pertenece una fecha, simplificando la lógica de agrupación y análisis de datos.
Descripción: Dada una fecha como objeto datetime o como cadena de texto,
esta función determina y devuelve el número del trimestre del año al que
corresponde esa fecha. Los trimestres se definen de la siguiente manera:
- Q1: Enero (1), Febrero (2), Marzo (3)
- Q2: Abril (4), Mayo (5), Junio (6)
- Q3: Julio (7), Agosto (8), Septiembre (9)
- Q4: Octubre (10), Noviembre (11), Diciembre (12)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Union[datetime, str]
|
La fecha de la cual se desea obtener el trimestre.
Puede ser un objeto |
required |
input_format
|
str
|
El formato de cadena de fecha (ej. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
El número del trimestre (1, 2, 3 o 4) al que pertenece la fecha. |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'date_input' no es un objeto |
ValueError
|
Si 'date_input' es una cadena y 'input_format' es |
Example
from datetime import datetime
Ejemplo con objeto datetime¶
get_quarter(datetime(2025, 8, 15)) # Agosto (mes 8) está en el Q3 3 get_quarter(datetime(2024, 1, 1)) # Enero (mes 1) está en el Q1 1 get_quarter(datetime(2023, 12, 31)) # Diciembre (mes 12) está en el Q4 4 get_quarter(datetime(2022, 4, 1)) # Abril (mes 4) está en el Q2 2
Ejemplo con cadena de fecha¶
get_quarter("2025-08-15", "%Y-%m-%d") 3 get_quarter("2024/02/29 10:30:00", "%Y/%m/%d %H:%M:%S") 1
Cadena de fecha sin formato (levantará ValueError)¶
try: get_quarter("2025-06-15") except ValueError as e: print(f"Error: {e}")
Expected output: Error: 'input_format' is required when 'date_input' is a string.¶
Formato incorrecto para cadena de fecha (levantará ValueError)¶
try: get_quarter("15-06-2025", "%Y-%m-%d") # Formato no coincide except ValueError as e: print(f"Error: {e}")
Expected output: Error: Could not parse date string '15-06-2025' with format '%Y-%m-%d'. Error: time data '15-06-2025' does not match format '%Y-%m-%d'¶
Cost: O(1), constant time for extracting month and calculating quarter.
Source code in shortfx/fxDate/date_operations.py
1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 | |
get_season(date_input: Union[datetime, str], hemisphere: str = 'northern', lang: str = 'en', format: Optional[str] = None) -> str
¶
Dada una fecha, devuelve la estación del año en el idioma especificado para el hemisferio indicado.
Problema/Necesidad del Usuario: Además de identificar la estación según el hemisferio, es fundamental que la respuesta se adapte al idioma del usuario y, potencialmente, a su localización para convenciones predeterminadas.
Objetivos del Producto: Proporcionar una función de contextualización de fechas más completa, que sea útil para aplicaciones globales que requieran respuestas localizadas y precisas estacionalmente.
Descripción: Esta función toma una fecha, un hemisferio ('northern' o 'southern'), y un código de idioma (ej. 'en' para inglés, 'es' para español). Devuelve el nombre de la estación meteorológica correspondiente. Las estaciones meteorológicas se definen por meses completos: - Hemisferio Norte: Primavera (Mar-May), Verano (Jun-Ago), Otoño (Sep-Nov), Invierno (Dic-Feb). - Hemisferio Sur: Otoño (Mar-May), Invierno (Jun-Ago), Primavera (Sep-Nov), Verano (Dic-Feb).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Union[datetime, str]
|
La fecha para la cual se desea obtener la estación.
Puede ser un objeto |
required |
hemisphere
|
str
|
El hemisferio para el cálculo de la estación. Puede ser 'northern' (hemisferio norte) o 'southern' (hemisferio sur). No es sensible a mayúsculas/minúsculas. Por defecto es 'northern'. |
'northern'
|
lang
|
str
|
El código de idioma para la respuesta (ej. 'en', 'es'). Por defecto es 'en' (inglés). |
'en'
|
format
|
str
|
El formato de cadena de fecha (ej. '%Y-%m-%d') si 'date_input' es una cadena. Es obligatorio si 'date_input' es una cadena. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
El nombre de la estación en el idioma especificado. |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'date_input' no es un objeto |
ValueError
|
Si 'hemisphere' no es 'northern' ni 'southern',
si 'lang' no es un idioma soportado,
o si 'format' es |
Example
from datetime import datetime
1. Verano en el Hemisferio Norte (inglés)¶
get_season(datetime(2025, 6, 11), 'northern', lang='en') 'Summer'
2. Invierno en el Hemisferio Sur (español)¶
get_season(datetime(2025, 6, 11), 'southern', lang='es') 'Invierno'
3. Otoño en el Hemisferio Norte (español, desde cadena)¶
get_season("2025-09-20", 'northern', lang='es', format="%Y-%m-%d") 'Otoño'
4. Hemisferio inválido (levantará ValueError)¶
try: get_season(datetime(2025, 6, 11), 'equator', lang='en') except ValueError as e: print(f"Error: {e}")
Expected output: Error: Invalid hemisphere. Must be 'northern' or 'southern'.¶
5. Idioma no soportado (levantará ValueError)¶
try: get_season(datetime(2025, 6, 11), 'northern', lang='fr') except ValueError as e: print(f"Error: {e}")
Expected output: Error: Unsupported language. Supported languages are: en, es.¶
Cost: O(1), constant time for date parsing and season determination.
Source code in shortfx/fxDate/date_operations.py
3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 | |
get_week_of_year(date_input: datetime) -> int
¶
Returns the ISO 8601 week number for a given date.
Delegates to :func:iso_week_number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The datetime object. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
ISO week number (1-53). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If date_input is not a datetime object. |
Example
from datetime import datetime get_week_of_year(datetime(2025, 6, 11)) 24
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
get_week_range(year: int, week_number: int) -> Tuple[datetime, datetime]
¶
Retrieves the start and end dates (Monday to Sunday) for a specific ISO week of a given year.
Cost: O(1), constant time for ISO week date calculation.
Source code in shortfx/fxDate/date_operations.py
get_working_days_in_range(start_date: datetime, end_date: datetime, holidays: Optional[List[datetime]] = None) -> int
¶
Calculates the number of working days within a given date range.
Problema/Necesidad del Usuario: Es común necesitar saber cuántos días hábiles hay entre dos fechas, excluyendo fines de semana y festivos definidos, para la planificación de proyectos, cálculo de plazos de entrega o métricas de eficiencia.
Objetivos del Producto: Proporcionar una función precisa para la planificación de recursos y la contabilidad de tiempo de trabajo, lo que es crucial en entornos empresariales.
Descripción: Esta función calcula el número de días hábiles (excluyendo sábados,
domingos y una lista opcional de festivos) dentro de un rango de fechas dado.
Tanto la fecha de inicio (start_date) como la fecha de fin (end_date)
son inclusivas en el cálculo si resultan ser días hábiles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime
|
La fecha de inicio del rango (inclusiva). |
required |
end_date
|
datetime
|
La fecha de fin del rango (inclusiva). |
required |
holidays
|
Optional[List[datetime]]
|
Una lista opcional de objetos |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
El número total de días hábiles en el rango especificado. |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'start_date' o 'end_date' no son objetos datetime, o si 'holidays' no es una lista de datetimes (o None). |
ValueError
|
Si 'start_date' es posterior a 'end_date'. |
Example
from datetime import datetime, date
Ejemplo 1: Rango de Lunes a Viernes sin festivos¶
get_working_days_in_range(datetime(2025, 6, 9), datetime(2025, 6, 13)) 5 # Lunes 9, Martes 10, Miércoles 11, Jueves 12, Viernes 13
Ejemplo 2: Rango que incluye un fin de semana¶
get_working_days_in_range(datetime(2025, 6, 9), datetime(2025, 6, 15)) 5 # Sábado 14 y Domingo 15 son excluidos
Ejemplo 3: Rango con festivos específicos¶
holiday_list = [datetime(2025, 6, 10), datetime(2025, 6, 12)] # Martes 10 y Jueves 12 son festivos get_working_days_in_range(datetime(2025, 6, 9), datetime(2025, 6, 13), holidays=holiday_list) 3 # Días hábiles: Lunes 9, Miércoles 11, Viernes 13
Ejemplo 4: Rango de un solo día (que es un fin de semana)¶
get_working_days_in_range(datetime(2025, 6, 14), datetime(2025, 6, 14)) # Sábado 14 0
Ejemplo 5: Rango de un solo día (que es un día hábil)¶
get_working_days_in_range(datetime(2025, 6, 11), datetime(2025, 6, 11)) # Miércoles 11 1
start_date después de end_date (levantará ValueError)¶
try: get_working_days_in_range(datetime(2025, 6, 13), datetime(2025, 6, 9)) except ValueError as e: print(f"Error: {e}")
Expected output: Error: start_date cannot be after end_date.¶
Lista de festivos con elemento no datetime (levantará TypeError)¶
try: get_working_days_in_range(datetime(2025, 6, 9), datetime(2025, 6, 13), holidays=[datetime(2025, 6, 10), "not_a_date"]) except TypeError as e: print(f"Error: {e}")
Expected output: Error: All items in 'holidays' list must be datetime objects.¶
Cost: O(n), where n is the number of days between start_date and end_date.
Source code in shortfx/fxDate/date_operations.py
2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 | |
get_year_calendar_by_weeks(year: int, start_date: Optional[datetime] = None, end_date: Optional[datetime] = None, granularity: str = 'week') -> list
¶
Generates a calendar table for a year, similar to DAX CALENDAR/CALENDARAUTO.
By default produces ISO-week rows (backward-compatible). When granularity
is "day" it returns one row per calendar day, matching
CALENDAR(start, end) / CALENDARAUTO() behaviour.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
The calendar year. Ignored when both start_date and end_date are supplied. |
required |
start_date
|
Optional[datetime]
|
Optional first date of the range (inclusive). Defaults to Jan 1 of year. |
None
|
end_date
|
Optional[datetime]
|
Optional last date of the range (inclusive). Defaults to Dec 31 of year. |
None
|
granularity
|
str
|
|
'week'
|
Returns:
| Type | Description |
|---|---|
list
|
When granularity is |
list
|
When granularity is |
Raises:
| Type | Description |
|---|---|
TypeError
|
If year is not an integer. |
ValueError
|
If year < 1 or granularity is invalid. |
Example
Legacy week-based calendar¶
cal = get_year_calendar_by_weeks(2023) cal[0] (1, datetime.datetime(2023, 1, 2, 0, 0), datetime.datetime(2023, 1, 8, 0, 0))
Day-level calendar (CALENDARAUTO style)¶
days = get_year_calendar_by_weeks(2023, granularity="day") days[0]["date"] datetime.date(2023, 1, 1)
Custom date range (CALENDAR style)¶
from datetime import datetime days = get_year_calendar_by_weeks( ... 2023, ... start_date=datetime(2023, 6, 1), ... end_date=datetime(2023, 6, 30), ... granularity="day", ... ) len(days) 30
Complexity: O(n) where n is the number of rows produced.
Source code in shortfx/fxDate/date_operations.py
1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 | |
human_readable_duration(seconds: Union[int, float]) -> str
¶
Format a number of seconds as a human-readable duration string.
Produces compact output like "2h 30m 15s", "3 days 4h", or
"1.5s" depending on magnitude.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seconds
|
Union[int, float]
|
Total seconds (can be float for sub-second precision). |
required |
Returns:
| Type | Description |
|---|---|
str
|
Human-readable duration string. |
Example
human_readable_duration(9015) '2h 30m 15s' human_readable_duration(90061) '1 day 1h 1m 1s' human_readable_duration(45) '45s'
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
intersection_of_date_ranges(start1: datetime, end1: datetime, start2: datetime, end2: datetime) -> Optional[Tuple[datetime, datetime]]
¶
Si dos rangos de fechas se solapan, devuelve una tupla con las fechas de inicio y fin del período de intersección. Si no hay solapamiento, devuelve None.
Problema/Necesidad del Usuario: Si dos rangos se superponen, a menudo es necesario saber cuál es el período de tiempo común entre ellos. Útil para análisis de concurrencia o cálculo de duraciones compartidas.
Objetivos del Producto: Extender la funcionalidad de detección de solapamientos para proporcionar el rango exacto de la superposición, lo que permite cálculos más precisos y lógica de negocio avanzada.
Descripción: Esta función toma cuatro objetos datetime que definen dos rangos de fechas:
[start1, end1] y [start2, end2]. Determina si estos rangos se superponen y, si lo hacen,
devuelve un nuevo rango (datetime, datetime) que representa la intersección.
Si los rangos solo se tocan en un punto (ej. [A, B] y [B, C]), el punto de contacto
(B, B) se considera la intersección.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start1
|
datetime
|
Fecha y hora de inicio del primer rango. |
required |
end1
|
datetime
|
Fecha y hora de fin del primer rango. |
required |
start2
|
datetime
|
Fecha y hora de inicio del segundo rango. |
required |
end2
|
datetime
|
Fecha y hora de fin del segundo rango. |
required |
Returns:
| Type | Description |
|---|---|
Optional[Tuple[datetime, datetime]]
|
Optional[Tuple[datetime, datetime]]: Una tupla |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si alguno de los argumentos no es un objeto |
ValueError
|
Si |
Example
from datetime import datetime
Ejemplo 1: Rangos con solapamiento (superposición parcial)¶
r1_start = datetime(2025, 6, 10, 10, 0, 0) r1_end = datetime(2025, 6, 15, 10, 0, 0) r2_start = datetime(2025, 6, 13, 10, 0, 0) r2_end = datetime(2025, 6, 18, 10, 0, 0) intersection_of_date_ranges(r1_start, r1_end, r2_start, r2_end) (datetime.datetime(2025, 6, 13, 10, 0), datetime.datetime(2025, 6, 15, 10, 0))
Ejemplo 2: Un rango contenido completamente en otro¶
r1_start = datetime(2025, 1, 1) r1_end = datetime(2025, 1, 31) r2_start = datetime(2025, 1, 10) r2_end = datetime(2025, 1, 20) intersection_of_date_ranges(r1_start, r1_end, r2_start, r2_end) (datetime.datetime(2025, 1, 10, 0, 0), datetime.datetime(2025, 1, 20, 0, 0))
Ejemplo 3: Rangos que no se solapan (rango1 antes de rango2)¶
r1_start = datetime(2025, 2, 1) r1_end = datetime(2025, 2, 10) r2_start = datetime(2025, 2, 15) r2_end = datetime(2025, 2, 20) intersection_of_date_ranges(r1_start, r1_end, r2_start, r2_end) is None True
Ejemplo 4: Rangos que solo se tocan en un punto¶
r1_start = datetime(2025, 3, 1) r1_end = datetime(2025, 3, 5) r2_start = datetime(2025, 3, 5) r2_end = datetime(2025, 3, 10) intersection_of_date_ranges(r1_start, r1_end, r2_start, r2_end) (datetime.datetime(2025, 3, 5, 0, 0), datetime.datetime(2025, 3, 5, 0, 0))
Ejemplo 5: Rangos inválidos (inicio > fin)¶
try: intersection_of_date_ranges(datetime(2025, 1, 10), datetime(2025, 1, 5), datetime(2025, 1, 1), datetime(2025, 1, 2)) except ValueError as e: print(f"Error: {e}")
Salida esperada: Error: start1 must be less than or equal to end1.¶
Ejemplo 6: Tipos de datos incorrectos¶
try: intersection_of_date_ranges("not a date", r1_end, r2_start, r2_end) except TypeError as e: print(f"Error: {e}")
Salida esperada: Error: All date range arguments must be datetime objects.¶
Source code in shortfx/fxDate/date_operations.py
3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 | |
is_between_dates(target_date: Union[datetime, str], start_date: Union[datetime, str], end_date: Union[datetime, str], inclusive: bool = True, format: Optional[str] = None) -> bool
¶
Comprueba si una 'target_date' se encuentra entre 'start_date' y 'end_date'.
Problema/Necesidad del Usuario: Es una operación extremadamente común verificar si una fecha cae dentro de un rango de fechas definido. Esto es vital para filtros, validaciones de disponibilidad, o reglas de negocio que aplican en ciertos periodos.
Objetivos del Producto: Simplificar la lógica de validación de rangos de fechas, haciéndola intuitiva y flexible (con la opción de incluir o excluir los límites).
Descripción: Dada una fecha objetivo (target_date), esta función verifica
si cae dentro del rango definido por start_date y end_date. Permite
especificar si el rango es inclusivo (los límites start_date y end_date
se consideran parte del rango) o exclusivo (la target_date debe ser
estrictamente entre start_date y end_date). Las fechas de entrada pueden
ser objetos datetime o cadenas de texto.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_date
|
Union[datetime, str]
|
La fecha que se desea comprobar. |
required |
start_date
|
Union[datetime, str]
|
La fecha de inicio del rango. |
required |
end_date
|
Union[datetime, str]
|
La fecha de fin del rango. |
required |
inclusive
|
bool
|
Si |
True
|
format
|
str
|
El formato de cadena de fecha (ej. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Raises:
| Type | Description |
|---|---|
TypeError
|
Si alguna de las fechas de entrada no es un objeto |
ValueError
|
Si alguna cadena de fecha no puede ser parseada con el formato
dado, si |
Example
from datetime import datetime
Ejemplo inclusivo (por defecto)¶
La fecha está dentro del rango¶
is_between_dates(datetime(2025, 6, 15), datetime(2025, 6, 1), datetime(2025, 6, 30)) True
La fecha es igual al límite inferior (inclusivo)¶
is_between_dates(datetime(2025, 6, 1), datetime(2025, 6, 1), datetime(2025, 6, 30)) True
La fecha es igual al límite superior (inclusivo)¶
is_between_dates(datetime(2025, 6, 30), datetime(2025, 6, 1), datetime(2025, 6, 30)) True
La fecha está fuera del rango¶
is_between_dates(datetime(2025, 7, 1), datetime(2025, 6, 1), datetime(2025, 6, 30)) False
Ejemplo exclusivo¶
La fecha está dentro del rango (exclusivo)¶
is_between_dates(datetime(2025, 6, 15), datetime(2025, 6, 1), datetime(2025, 6, 30), inclusive=False) True
La fecha es igual al límite inferior (exclusivo)¶
is_between_dates(datetime(2025, 6, 1), datetime(2025, 6, 1), datetime(2025, 6, 30), inclusive=False) False
La fecha es igual al límite superior (exclusivo)¶
is_between_dates(datetime(2025, 6, 30), datetime(2025, 6, 1), datetime(2025, 6, 30), inclusive=False) False
Ejemplo con cadenas de fecha (mismo formato para todas)¶
is_between_dates("2025-06-15 10:00:00", "2025-06-01 00:00:00", "2025-06-30 23:59:59", format="%Y-%m-%d %H:%M:%S") True
Sin formato para cadena de fecha (levantará ValueError)¶
try: is_between_dates("2025-06-15", datetime(2025, 6, 1), datetime(2025, 6, 30)) except ValueError as e: print(f"Error: {e}")
Expected output: Error: 'target_date_format' is required when 'target_date' is a string.¶
start_date después de end_date (levantará ValueError)¶
try: is_between_dates(datetime(2025, 6, 15), datetime(2025, 6, 30), datetime(2025, 6, 1)) except ValueError as e: print(f"Error: {e}")
Expected output: Error: start_date cannot be after end_date.¶
Cost: O(1), constant time for date comparisons.
Source code in shortfx/fxDate/date_operations.py
1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 | |
is_date_type(value: Any) -> bool
¶
Checks if an object is a date/time type (date, datetime, or time).
Description
Verifies if a value is one of Python's date/time types before performing operations, preventing type errors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
Any
|
The value to check. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if value is date, datetime, or time; False otherwise. |
Usage Example
from datetime import date, datetime, time from shortfx.fxDate.date_operations import is_date_type is_date_type(datetime(2026, 1, 3)) True is_date_type(date(2026, 1, 3)) True is_date_type(time(10, 30, 0)) True is_date_type("2026-01-03") False is_date_type(None) False
Cost: O(1)
Source code in shortfx/fxDate/date_operations.py
is_duration_greater_than(start_date: datetime, end_date: datetime, threshold_duration: timedelta) -> bool
¶
Comprueba si la duración entre start_date y end_date es estrictamente mayor que threshold_duration.
Problema/Necesidad del Usuario: La contraparte de la anterior: verificar si la duración es mayor que un umbral. Útil para identificar eventos de larga duración o violaciones de tiempo.
Objetivos del Producto: Complementar las validaciones de duración, permitiendo la detección de eventos que exceden ciertos límites de tiempo.
Descripción: Esta función calcula la duración absoluta entre start_date y end_date
y la compara con threshold_duration. Retorna True si la duración calculada es
estrictamente mayor que el umbral, y False en cualquier otro caso (menor o igual).
No importa el orden de start_date y end_date, ya que la duración se calcula
como un valor absoluto.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime
|
La fecha y hora de inicio. |
required |
end_date
|
datetime
|
La fecha y hora de fin. |
required |
threshold_duration
|
timedelta
|
La duración de umbral con la que comparar. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Raises:
| Type | Description |
|---|---|
TypeError
|
Si |
Example
from datetime import datetime, timedelta
Ejemplo 1: Duración mayor que el umbral¶
is_duration_greater_than(datetime(2025, 6, 11, 10, 0), datetime(2025, 6, 11, 10, 45), timedelta(minutes=30)) True
(45 minutos > 30 minutos)¶
Ejemplo 2: Duración igual al umbral (debe ser False porque es estrictamente mayor)¶
is_duration_greater_than(datetime(2025, 6, 11, 10, 0), datetime(2025, 6, 11, 10, 30), timedelta(minutes=30)) False
(30 minutos > 30 minutos) es Falso¶
Ejemplo 3: Duración menor que el umbral¶
is_duration_greater_than(datetime(2025, 6, 11, 10, 0), datetime(2025, 6, 11, 10, 15), timedelta(minutes=30)) False
(15 minutos > 30 minutos) es Falso¶
Ejemplo 4: Fechas en orden invertido¶
is_duration_greater_than(datetime(2025, 6, 11, 10, 45), datetime(2025, 6, 11, 10, 0), timedelta(minutes=30)) True
(45 minutos > 30 minutos)¶
Ejemplo 5: Tipos de datos incorrectos¶
try: is_duration_greater_than(datetime(2025, 6, 11, 10, 0), "2025-06-11", timedelta(minutes=30)) except TypeError as e: print(f"Error: {e}")
Salida esperada: Error: start_date and end_date must be datetime objects.¶
Source code in shortfx/fxDate/date_operations.py
4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 | |
is_duration_less_than(start_date: datetime, end_date: datetime, threshold_duration: timedelta) -> bool
¶
Comprueba si la duración entre start_date y end_date es estrictamente menor que threshold_duration.
Problema/Necesidad del Usuario: Validar si la duración entre dos fechas es menor que un umbral específico. Muy útil para SLAs (Acuerdos de Nivel de Servicio), plazos o límites de tiempo.
Objetivos del Producto: Proporcionar una forma clara y concisa de validar la duración de un evento o un período, esencial para reglas de negocio basadas en el tiempo.
Descripción: Esta función calcula la duración absoluta entre start_date y end_date
y la compara con threshold_duration. Retorna True si la duración calculada es
estrictamente menor que el umbral, y False en cualquier otro caso (mayor o igual).
No importa el orden de start_date y end_date, ya que la duración se calcula
como un valor absoluto.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime
|
La fecha y hora de inicio. |
required |
end_date
|
datetime
|
La fecha y hora de fin. |
required |
threshold_duration
|
timedelta
|
La duración de umbral con la que comparar. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Raises:
| Type | Description |
|---|---|
TypeError
|
Si |
Example
from datetime import datetime, timedelta
Ejemplo 1: Duración menor que el umbral¶
is_duration_less_than(datetime(2025, 6, 11, 10, 0), datetime(2025, 6, 11, 10, 20), timedelta(minutes=30)) True
(20 minutos < 30 minutos)¶
Ejemplo 2: Duración igual al umbral (debe ser False porque es estrictamente menor)¶
is_duration_less_than(datetime(2025, 6, 11, 10, 0), datetime(2025, 6, 11, 10, 30), timedelta(minutes=30)) False
(30 minutos < 30 minutos) es Falso¶
Ejemplo 3: Duración mayor que el umbral¶
is_duration_less_than(datetime(2025, 6, 11, 10, 0), datetime(2025, 6, 11, 10, 45), timedelta(minutes=30)) False
(45 minutos < 30 minutos) es Falso¶
Ejemplo 4: Fechas en orden invertido (la duración absoluta sigue siendo la misma)¶
is_duration_less_than(datetime(2025, 6, 11, 10, 20), datetime(2025, 6, 11, 10, 0), timedelta(minutes=30)) True
(20 minutos < 30 minutos)¶
Ejemplo 5: Tipos de datos incorrectos¶
try: is_duration_less_than("2025-06-11", datetime(2025, 6, 11, 10, 20), timedelta(minutes=30)) except TypeError as e: print(f"Error: {e}")
Salida esperada: Error: start_date and end_date must be datetime objects.¶
Source code in shortfx/fxDate/date_operations.py
4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 | |
is_leap_year(year: int) -> bool
¶
Checks if a given year is a leap year.
A leap year occurs every four years, except for years that are divisible by 100 but not by 400.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
The year to check (e.g., 2024). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the year is a leap year, False otherwise. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'year' is not an integer. |
ValueError
|
If 'year' is less than 1. |
Example
is_leap_year(2024) True is_leap_year(2023) False is_leap_year(2000) # Divisible by 400, so it's a leap year True is_leap_year(1900) # Divisible by 100 but not by 400, so NOT a leap year False
Cost: O(1), constant time for arithmetic operations.
Source code in shortfx/fxDate/date_operations.py
is_same_business_day(date1: Union[datetime, date], date2: Union[datetime, date], holidays: Optional[List] = None) -> bool
¶
Check whether two dates fall on the same business day.
A date that falls on a weekend or listed holiday is not considered a business day, so two dates can only be the "same business day" if they share the same calendar date and that date is Mon–Fri and not a holiday.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date1
|
Union[datetime, date]
|
First date. |
required |
date2
|
Union[datetime, date]
|
Second date. |
required |
holidays
|
Optional[List]
|
Optional list of holiday dates. |
None
|
Returns:
| Type | Description |
|---|---|
bool
|
True if both dates share the same business day. |
Example
from datetime import date is_same_business_day(date(2025, 6, 16), date(2025, 6, 16)) True is_same_business_day(date(2025, 6, 14), date(2025, 6, 14)) False
Complexity: O(h) where h = len(holidays)
Source code in shortfx/fxDate/date_operations.py
is_valid_date(date_input: Any, date_format: str = '%Y-%m-%d') -> bool
¶
Validates if input is a valid date (datetime object or parseable string).
Description
Checks whether the input is a valid date. Accepts datetime objects or strings that can be parsed with the specified format. Ensures inputs represent actual dates before use in date operations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Any
|
The parameter to validate (datetime object or string). |
required |
date_format
|
str
|
Expected format if date_input is a string. Defaults to "%Y-%m-%d". |
'%Y-%m-%d'
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if date_input is valid date, False otherwise. |
Usage Example
from datetime import datetime from shortfx.fxDate.date_operations import is_valid_date is_valid_date(datetime(2026, 1, 3)) True is_valid_date("2026-01-03") True is_valid_date("03/01/2026", "%d/%m/%Y") True is_valid_date("2026-13-01") # Invalid month False is_valid_date("not-a-date") False
Cost: O(1)
Source code in shortfx/fxDate/date_operations.py
is_valid_time(hour: int, minute: int, second: int = 0, microsecond: int = 0) -> bool
¶
Verifica si una combinación de hora, minuto, segundo y microsegundo dada representa una hora válida.
Problema/Necesidad del Usuario: Al recibir entradas de tiempo de usuario, es crucial validar que los componentes de la hora (horas, minutos, segundos) sean lógicamente posibles (ej. no "25:00:00").
Objetivos del Producto: Mejorar la robustez de la entrada de datos de tiempo, reduciendo errores y validaciones en capas superiores de la aplicación.
Descripción: Esta función toma valores enteros para la hora, minuto, segundo y microsegundo.
Devuelve True si todos los componentes están dentro de sus rangos válidos
(ej., hora entre 0 y 23, minuto/segundo entre 0 y 59, microsegundo entre 0 y 999999).
Si alguno de los componentes no es un entero o está fuera de su rango válido,
la función devuelve False.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hour
|
int
|
La hora a validar (0-23). |
required |
minute
|
int
|
El minuto a validar (0-59). |
required |
second
|
int
|
El segundo a validar (0-59). Por defecto es 0. |
0
|
microsecond
|
int
|
El microsegundo a validar (0-999999). Por defecto es 0. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Example
Ejemplos de uso¶
is_valid_time(23, 59, 59) True is_valid_time(0, 0, 0, 0) True is_valid_time(12, 30) # Sin segundos ni microsegundos True is_valid_time(25, 0, 0) # Hora inválida False is_valid_time(10, 60, 0) # Minuto inválido False is_valid_time(1, 1, 60) # Segundo inválido False is_valid_time(1, 1, 1, 1000000) # Microsegundo inválido False is_valid_time(-1, 0, 0) # Hora negativa False is_valid_time(10, 0, 'abc') # Tipo de dato incorrecto False
Cost: O(1), constant time for validation checks.
Source code in shortfx/fxDate/date_operations.py
1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 | |
is_weekend(date_input: Union[datetime, str], input_format: str = None, language: str = 'en') -> bool
¶
Determines if a given date is a Saturday or a Sunday.
This function accepts either a datetime object or a date string. If a string is provided, its format must be specified. The 'language' parameter is primarily for internal use or future expansion related to locale-specific date processing, though the function itself returns a boolean indicating weekend status.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Union[datetime, str]
|
The date to check. Can be a datetime object (e.g., datetime(2023, 10, 28)) or a string (e.g., "28/10/2023"). |
required |
input_format
|
str
|
The format code string for 'date_input' if it's a string. Required if 'date_input' is a string. E.g., '%d/%m/%Y' for "28/10/2023". Not used if 'date_input' is a datetime object. |
None
|
language
|
str
|
The two-letter ISO 639-1 language code (e.g., 'en', 'es', 'fr', 'de'). This parameter is available for consistency with other date functions that use locales, but it doesn't directly affect the boolean output of this specific function. Defaults to 'en'. |
'en'
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if the date is a Saturday or Sunday, False otherwise. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'date_input' is not a datetime object or a string. |
ValueError
|
If 'date_input' is a string and 'input_format' is not provided, or if the string cannot be parsed with the given format. Also, if the specified 'language' cannot be set as a locale on your system. |
Example
from datetime import datetime
Saturday (using datetime object)¶
is_weekend(datetime(2023, 10, 28)) True
Sunday (using datetime object)¶
is_weekend(datetime(2023, 10, 29)) True
Friday (using datetime object)¶
is_weekend(datetime(2023, 10, 27)) False
Saturday (using a string input with format)¶
is_weekend("28/10/2023", "%d/%m/%Y") True
Monday (using a string input with format)¶
is_weekend("30-10-2023", "%d-%m-%Y") False
Using 'es' language (parameter included, but output is still boolean)¶
is_weekend(datetime(2023, 10, 28), language='es') True
Cost: O(1), constant time for weekday check.
Source code in shortfx/fxDate/date_operations.py
3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 | |
is_working_day(date_input: Union[datetime, str], input_format: str = None, system: Literal['european', 'anglo'] = 'european') -> bool
¶
Checks if a given date is a working day (Monday to Friday) based on the specified week numbering system.
This function determines if a date falls on a weekday (Monday through Friday), allowing for the consideration of different week numbering systems. The definition of working days (Monday-Friday) remains consistent across systems, but their numerical representation differs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Union[datetime, str]
|
The date to check.
Can be a datetime object (e.g., |
required |
input_format
|
str
|
The format code string for |
None
|
system
|
Literal['european', 'anglo']
|
The week numbering system to use for
interpreting the day of the week.
- |
'european'
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
ValueError
|
If |
Example
from datetime import datetime
A Monday (June 9, 2025, was a Monday)¶
is_working_day(datetime(2025, 6, 9), system='european') # Monday = 0 in European system True is_working_day(datetime(2025, 6, 9), system='anglo') # Monday = 1 in anglo system True
A Saturday (June 14, 2025, will be a Saturday)¶
is_working_day(datetime(2025, 6, 14), system='european') # Saturday = 5 in European system False is_working_day(datetime(2025, 6, 14), system='anglo') # Saturday = 6 in anglo system False
Using string input for a Thursday (June 12, 2025, will be a Thursday)¶
is_working_day("12/06/2025", "%d/%m/%Y", system='european') True is_working_day("12/06/2025", "%d/%m/%Y", system='anglo') True
Cost: O(1), constant time for weekday calculation and comparison.
Source code in shortfx/fxDate/date_operations.py
3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 | |
iso_week_number(date_input: datetime) -> int
¶
Returns the ISO 8601 week number for a given date.
Description
The ISO week number ranges from 1 to 53. Week 1 is the week containing the first Thursday of the year.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The date to evaluate. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
ISO week number (1-53). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If date_input is not a datetime object. |
Example
from datetime import datetime iso_week_number(datetime(2025, 1, 1)) 1 iso_week_number(datetime(2025, 6, 15)) 24
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
iso_week_start(year: int, week: int) -> date
¶
Return the Monday that starts a given ISO week.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
ISO year. |
required |
week
|
int
|
ISO week number (1-53). |
required |
Returns:
| Type | Description |
|---|---|
date
|
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If arguments are not integers. |
ValueError
|
If week is outside [1, 53]. |
Example
iso_week_start(2026, 1) datetime.date(2025, 12, 29)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
last_day_of_month(date_input: Union[datetime, str], input_format: str = None) -> datetime
¶
Returns the last day of the month for a given date.
Description
Convenience alias for end_of_month with a more intuitive name.
Called by date_sys.current_last_day_of_month.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Union[datetime, str]
|
A datetime object or date string. |
required |
input_format
|
str
|
Format string when date_input is a string. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
Last day of the month at end-of-day (23:59:59.999999). |
Example
last_day_of_month(datetime(2025, 2, 10)) datetime.datetime(2025, 2, 28, 23, 59, 59, 999999)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
last_day_of_week(date_input: Union[datetime, str], week_start_day: int = 0) -> datetime
¶
Calcula el último día de la semana para una fecha dada, permitiendo la personalización del día de inicio de la semana.
Problema/Necesidad del Usuario: Es necesario encontrar el último día de la semana para una fecha específica, lo que es útil para cerrar períodos de informe, definir agregaciones semanales o completar ciclos de tareas.
Objetivos del Producto: Proporcionar una función flexible que determine el día final de la semana para cualquier fecha, adaptándose a diversas convenciones de calendario mediante la especificación del día de inicio de semana.
Descripción: Dada una fecha y un día de inicio de semana (por defecto Lunes),
esta función devuelve un objeto datetime que representa el último día de la
semana que contiene la fecha dada. El día de inicio de semana se especifica
como un entero (0=Lunes, 1=Martes, ..., 6=Domingo). La fecha devuelta tendrá
su componente de tiempo establecido a las 23:59:59.999999 (final del día).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Union[datetime, str]
|
La fecha para la cual se desea encontrar
el último día de la semana. Puede ser un
objeto |
required |
week_start_day
|
int
|
Un entero que representa el día que se considera el inicio de la semana (0=Lunes, 1=Martes, ..., 6=Domingo). Por defecto es 0 (Lunes). |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
Un objeto |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'date_input' no es un objeto |
ValueError
|
Si 'week_start_day' no está entre 0 y 6, o si la cadena de fecha no puede ser parseada. |
Example
from datetime import datetime
Ejemplo 1: Obtener el último día de la semana (Lunes como inicio) para el 11 de junio de 2025 (Miércoles)¶
last_day_of_week(datetime(2025, 6, 11)) datetime.datetime(2025, 6, 15, 23, 59, 59, 999999) # El domingo de esa semana es el 15 de junio
Ejemplo 2: Obtener el último día de la semana (Domingo como inicio) para el 15 de junio de 2025 (Domingo)¶
last_day_of_week(datetime(2025, 6, 15), week_start_day=6) datetime.datetime(2025, 6, 21, 23, 59, 59, 999999) # El sábado de esa semana es el 21 de junio
Ejemplo 3: Usando una cadena de fecha¶
last_day_of_week("2025-06-11", week_start_day=0) datetime.datetime(2025, 6, 15, 23, 59, 59, 999999)
Ejemplo 4: Día de inicio de semana inválido (levantará ValueError)¶
try: last_day_of_week(datetime(2025, 6, 11), week_start_day=8) except ValueError as e: print(f"Error: {e}")
Expected output: Error: week_start_day must be between 0 (Monday) and 6 (Sunday).¶
Cost: O(1), constant time for date arithmetic operations.
Source code in shortfx/fxDate/date_operations.py
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 | |
last_weekday_of_month(date_input: datetime, target_weekday: int) -> datetime
¶
Returns the last occurrence of a specific weekday in the month of a given date.
Description
Finds the last day in the month that matches target_weekday. Useful for recurring schedules like "last Friday of the month".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
Any date within the target month. |
required |
target_weekday
|
int
|
Weekday as integer (0=Monday … 6=Sunday). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
The last matching weekday of the month at midnight. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If date_input is not a datetime object. |
ValueError
|
If target_weekday is not in 0‑6. |
Example
import calendar last_weekday_of_month(datetime(2025, 6, 1), calendar.FRIDAY) datetime.datetime(2025, 6, 27, 0, 0) last_weekday_of_month(datetime(2024, 2, 10), calendar.THURSDAY) datetime.datetime(2024, 2, 29, 0, 0)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
midpoint_date(d1, d2)
¶
Return the midpoint date between two dates.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d1
|
First date. |
required | |
d2
|
Second date. |
required |
Returns:
| Type | Description |
|---|---|
|
Midpoint as a |
Raises:
| Type | Description |
|---|---|
TypeError
|
If arguments are not date/datetime. |
Example
from datetime import date midpoint_date(date(2024, 1, 1), date(2024, 1, 11)) datetime.date(2024, 1, 6)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
month_name(date_input: datetime, language: str = 'en') -> str
¶
Gets the name of the month for a given date in the specified language.
This function leverages your operating system's installed locales to provide month names in various languages. The availability of a specific language (locale) depends entirely on what is configured and installed on your operating system. For example, 'es' for Spanish, 'fr' for French, 'de' for German, etc.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The datetime object for which to get the month name. |
required |
language
|
str
|
The two-letter ISO 639-1 language code (e.g., 'en', 'es', 'fr', 'de'). Defaults to 'en'. |
'en'
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
The full name of the month (e.g., 'October', 'Octubre', 'Oktober', 'Oktober'). Note: Capitalization might vary based on the specific locale installed on your system. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'date_input' is not a datetime object. |
ValueError
|
If the specified 'language' cannot be set as a locale on your system. This usually means the corresponding language pack is not installed or the locale name is not recognized by your OS. |
Example
from datetime import datetime
Example for English (always available)¶
month_name(datetime(2023, 10, 26), 'en') 'October'
Example for Spanish (requires 'es' or 'es_ES.UTF-8' locale installed on your system)¶
try: month_name(datetime(2023, 10, 26), 'es') except ValueError as e: print(f"Could not get Spanish month name: {e}")
Expected output (if locale installed): 'octubre' or 'Octubre'¶
Example for German (requires 'de' or 'de_DE.UTF-8' locale installed on your system)¶
try: month_name(datetime(2023, 10, 26), 'de') except ValueError as e: print(f"Could not get German month name: {e}")
Expected output (if locale installed): 'Oktober'¶
Cost: O(1), constant time for locale operations and string formatting.
Source code in shortfx/fxDate/date_operations.py
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 | |
months_between_dates(start_date: datetime, end_date: datetime) -> int
¶
Calcula el número de meses completos transcurridos entre dos fechas.
Problema/Necesidad del Usuario: Es necesario obtener el número de meses entre dos fechas para cálculos de antigüedad, proyecciones financieras o la duración de proyectos, requiriendo un manejo preciso de los límites de mes.
Objetivos del Producto: Proporcionar una función fiable para cuantificar la duración en términos de meses completos entre dos puntos en el tiempo.
Descripción: Esta función toma dos objetos datetime, una fecha de inicio y una
fecha de fin. Calcula la diferencia en meses enteros entre ellas.
Por ejemplo, del 15 de enero al 14 de febrero es 0 meses. Del 15 de enero al 15 de febrero es 1 mes.
La función maneja correctamente el orden de las fechas: si start_date es posterior
a end_date, el resultado será un número negativo.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime
|
La fecha de inicio. |
required |
end_date
|
datetime
|
La fecha de fin. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
El número de meses completos entre |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si |
Example
from datetime import datetime
Ejemplo 1: 0 meses (mismo mes)¶
months_between_dates(datetime(2023, 1, 10), datetime(2023, 1, 25)) 0
Ejemplo 2: 1 mes (del 10 de enero al 10 de febrero)¶
months_between_dates(datetime(2023, 1, 10), datetime(2023, 2, 10)) 1
Ejemplo 3: Más de un mes (del 10 de enero al 9 de marzo)¶
months_between_dates(datetime(2023, 1, 10), datetime(2023, 3, 9)) 1
Ejemplo 4: Múltiples meses completos¶
months_between_dates(datetime(2023, 1, 1), datetime(2023, 7, 31)) 6
Ejemplo 5: Orden invertido (resultado negativo)¶
months_between_dates(datetime(2023, 5, 1), datetime(2023, 2, 1)) -3
Ejemplo 6: Con horas y minutos (no afectan el cálculo de meses completos)¶
months_between_dates(datetime(2023, 1, 31, 23, 59, 59), datetime(2023, 3, 1, 0, 0, 0)) 1 # De enero 31 a marzo 1, solo se ha completado febrero.
Ejemplo 7: Tipos de datos incorrectos¶
try: months_between_dates("2023-01-01", datetime(2023, 2, 1)) except TypeError as e: print(f"Error: {e}")
Salida esperada: Error: start_date and end_date must be datetime objects.¶
Cost: O(1), constant time for date arithmetic and month calculation.
Source code in shortfx/fxDate/date_operations.py
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 | |
network_days_intl(start_date: datetime, end_date: datetime, weekend: Union[int, str] = 1, holidays: Optional[List[datetime]] = None) -> int
¶
Calculates working days between two dates with custom weekend definition.
Description
Extension of get_working_days_in_range that allows specifying which days are considered weekends. Weekend can be an integer preset (1-7) or a 7-character string of 0s/1s (Monday-Sunday, 1 = weekend day).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime
|
The start date (inclusive). |
required |
end_date
|
datetime
|
The end date (inclusive). |
required |
weekend
|
Union[int, str]
|
Weekend definition. Integer presets: 1 = Sat-Sun (default), 2 = Sun-Mon, 3 = Mon-Tue, 4 = Tue-Wed, 5 = Wed-Thu, 6 = Thu-Fri, 7 = Fri-Sat. Or a 7-char string of 0/1 (Mon-Sun), e.g. '0000011' = Sat-Sun. |
1
|
holidays
|
Optional[List[datetime]]
|
Optional list of holiday datetimes to exclude. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Number of working days. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If dates are not datetime objects. |
ValueError
|
If start_date > end_date or weekend value is invalid. |
Example
from datetime import datetime network_days_intl(datetime(2025, 1, 6), datetime(2025, 1, 10)) 5 network_days_intl(datetime(2025, 1, 6), datetime(2025, 1, 12), weekend='0000011') 5
Complexity: O(n) where n is the number of days in the range
Source code in shortfx/fxDate/date_operations.py
networkdays(start_date: Union[date, datetime], end_date: Union[date, datetime], holidays: Union[List[Union[date, datetime]], None] = None) -> int
¶
Counts working days (Mon-Fri) between two dates, excluding holidays.
Description
Returns the number of business days between start_date and end_date, both inclusive. Weekends (Saturday, Sunday) and optional holidays are excluded. Equivalent to Excel NETWORKDAYS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
Union[date, datetime]
|
The start date. |
required |
end_date
|
Union[date, datetime]
|
The end date. |
required |
holidays
|
Union[List[Union[date, datetime]], None]
|
Optional list of holiday dates to exclude. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Number of working days. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If dates are not date/datetime objects. |
Example
from datetime import date networkdays(date(2025, 1, 1), date(2025, 1, 10)) 8 networkdays(date(2025, 1, 1), date(2025, 1, 10), [date(2025, 1, 6)]) 7
Complexity: O(n) where n is the number of days in the range
Source code in shortfx/fxDate/date_operations.py
6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 | |
networkdays_intl(start_date: Union[date, datetime], end_date: Union[date, datetime], weekend: Union[int, str] = 1, holidays: Optional[List[Union[date, datetime]]] = None) -> int
¶
Counts working days between two dates with custom weekends.
Description
Like networkdays but allows specifying which days count as weekends via an integer preset (1-7) or a 7-character binary string. Equivalent to Excel NETWORKDAYS.INTL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
Union[date, datetime]
|
The start date (inclusive). |
required |
end_date
|
Union[date, datetime]
|
The end date (inclusive). |
required |
weekend
|
Union[int, str]
|
Weekend definition. Integer 1-7 for presets or a 7-char string of '0'/'1' (Mon-Sun) where '1' = weekend day. |
1
|
holidays
|
Optional[List[Union[date, datetime]]]
|
Optional list of holiday dates to exclude. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Number of working days. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If dates are not date/datetime objects. |
ValueError
|
If weekend parameter is invalid. |
Example
from datetime import date networkdays_intl(date(2025, 1, 6), date(2025, 1, 10)) 5 networkdays_intl(date(2025, 1, 6), date(2025, 1, 10), weekend=2) 4
Complexity: O(n) where n is the number of days in the range
Source code in shortfx/fxDate/date_operations.py
6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 | |
next_business_day(d: Union[datetime, date], holidays: Optional[List[Union[datetime, date]]] = None) -> date
¶
Returns the next business day after the given date.
Skips weekends (Saturday/Sunday) and optionally provided holidays.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
Union[datetime, date]
|
Starting date. |
required |
holidays
|
Optional[List[Union[datetime, date]]]
|
Optional list of holiday dates to skip. |
None
|
Returns:
| Type | Description |
|---|---|
date
|
The next business day as a date object. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If d is not a date/datetime. |
Example
from datetime import date next_business_day(date(2026, 4, 3)) # Friday datetime.date(2026, 4, 6) next_business_day(date(2026, 4, 4)) # Saturday datetime.date(2026, 4, 6)
Complexity: O(h) where h is the number of consecutive holidays.
Source code in shortfx/fxDate/date_operations.py
next_full_moon(d: date | datetime) -> date
¶
Approximate date of the next full moon after d.
Uses the mean synodic month (29.53058867 days) anchored to a known full moon (2000-01-06 18:14 UTC).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
date | datetime
|
Reference date. |
required |
Returns:
| Type | Description |
|---|---|
date
|
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If d is not a date or datetime. |
Example
next_full_moon(date(2026, 1, 1)) datetime.date(2026, 1, 3)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
next_occurrence(weekday: int, hour: int = 0, minute: int = 0, ref: date | datetime | None = None) -> datetime
¶
Find the next occurrence of a given weekday and time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
weekday
|
int
|
ISO weekday (1=Monday … 7=Sunday). |
required |
hour
|
int
|
Hour component (0-23). Default 0. |
0
|
minute
|
int
|
Minute component (0-59). Default 0. |
0
|
ref
|
date | datetime | None
|
Reference date/datetime. Defaults to today. |
None
|
Returns:
| Type | Description |
|---|---|
datetime
|
A |
datetime
|
relative to ref). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If weekday is not an integer. |
ValueError
|
If weekday not in 1-7 or hour/minute out of range. |
Example
from datetime import date
Next Monday after 2026-04-08 (Wednesday)¶
next_occurrence(1, ref=date(2026, 4, 8)) datetime.datetime(2026, 4, 13, 0, 0)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
next_weekday(date_input: datetime, target_weekday: int) -> datetime
¶
Returns the next occurrence of a specific weekday after a given date.
Description
Calculates the nearest future date matching the target weekday. If the given date already falls on the target weekday, returns the same weekday of the following week.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The starting date. |
required |
target_weekday
|
int
|
Weekday as integer (0=Monday … 6=Sunday). Constants
from the |
required |
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
The next occurrence at midnight. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If date_input is not a datetime object. |
ValueError
|
If target_weekday is not in 0‑6. |
Example
import calendar next_weekday(datetime(2025, 6, 9), calendar.FRIDAY) datetime.datetime(2025, 6, 13, 0, 0) next_weekday(datetime(2025, 6, 13), calendar.FRIDAY) datetime.datetime(2025, 6, 20, 0, 0)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
overlap_dates(start1: Union[str, date, datetime], end1: Union[str, date, datetime], start2: Union[str, date, datetime], end2: Union[str, date, datetime]) -> bool
¶
Checks whether two date ranges overlap.
Two ranges overlap when one starts before the other ends, and vice versa.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start1
|
Union[str, date, datetime]
|
Start of the first range. |
required |
end1
|
Union[str, date, datetime]
|
End of the first range. |
required |
start2
|
Union[str, date, datetime]
|
Start of the second range. |
required |
end2
|
Union[str, date, datetime]
|
End of the second range. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the ranges share at least one common day. |
Example
from datetime import date overlap_dates(date(2026, 1, 1), date(2026, 1, 10), date(2026, 1, 5), date(2026, 1, 15)) True overlap_dates(date(2026, 1, 1), date(2026, 1, 10), date(2026, 1, 11), date(2026, 1, 20)) False
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
overlap_days(start1: date, end1: date, start2: date, end2: date) -> int
¶
Counts the overlapping days between two date ranges.
Both ranges are inclusive on both ends.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start1
|
date
|
Start of the first range. |
required |
end1
|
date
|
End of the first range. |
required |
start2
|
date
|
Start of the second range. |
required |
end2
|
date
|
End of the second range. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Number of overlapping days (0 if no overlap). |
Example
from datetime import date overlap_days(date(2026, 1, 1), date(2026, 1, 10), ... date(2026, 1, 5), date(2026, 1, 15)) 6
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
parts_to_date(year: int, month: int, day: int) -> date
¶
Create a date from year, month and day with overflow support.
Overflowing values are normalised automatically: month 14 becomes February of the next year, day 0 becomes the last day of the previous month, day 32 rolls into the next month, etc.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
Year component. |
required |
month
|
int
|
Month component (may overflow beyond 1-12). |
required |
day
|
int
|
Day component (may overflow; 0 = last day of previous month). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
date |
date
|
The resulting date after normalisation. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If any argument is not an integer. |
Example
parts_to_date(2025, 10, 30) datetime.date(2025, 10, 30) parts_to_date(2024, 14, 1) datetime.date(2025, 2, 1) parts_to_date(2024, 3, 0) datetime.date(2024, 2, 29) parts_to_date(2024, 1, -1) datetime.date(2023, 12, 30) parts_to_date(2024, 0, 15) datetime.date(2023, 12, 15)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
parts_to_datetime(year: int, month: int, day: int, hour: int = 0, minute: int = 0, second: int = 0, microsecond: int = 0) -> datetime
¶
Create a datetime from components with overflow support.
Overflowing values are normalised: month 14 rolls into the next year, day 0 becomes the last day of the previous month, hour 25 becomes 01:00 of the next day, etc.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
Year component. |
required |
month
|
int
|
Month component (may overflow). |
required |
day
|
int
|
Day component (may overflow; 0 = last day of prev. month). |
required |
hour
|
int
|
Hour component (default 0, may overflow). |
0
|
minute
|
int
|
Minute component (default 0, may overflow). |
0
|
second
|
int
|
Second component (default 0, may overflow). |
0
|
microsecond
|
int
|
Microsecond component (default 0, may overflow). |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
The resulting datetime after normalisation. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If any argument is not an integer. |
Example
parts_to_datetime(2025, 10, 30, 15, 30, 45) datetime.datetime(2025, 10, 30, 15, 30, 45) parts_to_datetime(2025, 1, 1) datetime.datetime(2025, 1, 1, 0, 0) parts_to_datetime(2024, 1, 1, 25, 0, 0) datetime.datetime(2024, 1, 2, 1, 0)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
parts_to_time(hour: int = 0, minute: int = 0, second: int = 0, microsecond: int = 0) -> time
¶
Create a time object from hour, minute and second with overflow.
Overflowing values wrap around a 24-hour clock: 90 minutes becomes 1 hour 30 minutes, 25 hours wraps to 01:00, etc.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hour
|
int
|
Hour component (may overflow, wraps mod 24). |
0
|
minute
|
int
|
Minute component (may overflow). |
0
|
second
|
int
|
Second component (may overflow). |
0
|
microsecond
|
int
|
Microsecond component (may overflow). |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
time |
time
|
The resulting time after normalisation. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If any argument is not an integer. |
Example
parts_to_time(14, 30, 0) datetime.time(14, 30) parts_to_time(25, 0, 0) datetime.time(1, 0) parts_to_time(0, 90, 0) datetime.time(1, 30)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
previous_business_day(d: Union[datetime, date], holidays: Optional[List[Union[datetime, date]]] = None) -> date
¶
Returns the previous business day before the given date.
Skips weekends (Saturday/Sunday) and optionally provided holidays.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
Union[datetime, date]
|
Starting date. |
required |
holidays
|
Optional[List[Union[datetime, date]]]
|
Optional list of holiday dates to skip. |
None
|
Returns:
| Type | Description |
|---|---|
date
|
The previous business day as a date object. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If d is not a date/datetime. |
Example
from datetime import date previous_business_day(date(2026, 4, 6)) # Monday datetime.date(2026, 4, 3) previous_business_day(date(2026, 4, 5)) # Sunday datetime.date(2026, 4, 3)
Complexity: O(h) where h is the number of consecutive holidays.
Source code in shortfx/fxDate/date_operations.py
previous_weekday(date_input: datetime, target_weekday: int) -> datetime
¶
Returns the most recent occurrence of a specific weekday before a given date.
Description
Calculates the nearest past date matching the target weekday. If the given date already falls on the target weekday, returns that same date.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The starting date. |
required |
target_weekday
|
int
|
Weekday as integer (0=Monday … 6=Sunday). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
The previous (or current) occurrence at midnight. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If date_input is not a datetime object. |
ValueError
|
If target_weekday is not in 0‑6. |
Example
import calendar previous_weekday(datetime(2025, 6, 9), calendar.FRIDAY) datetime.datetime(2025, 6, 6, 0, 0) previous_weekday(datetime(2025, 6, 6), calendar.FRIDAY) datetime.datetime(2025, 6, 6, 0, 0)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
quarters_between_dates(start_date: datetime, end_date: datetime) -> int
¶
Calculates the number of complete quarters between two dates.
Description
Returns the whole-quarter difference. A positive result means end_date is after start_date; negative means it is before.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime
|
The start date. |
required |
end_date
|
datetime
|
The end date. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Number of quarters between the dates. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If start_date or end_date are not datetime objects. |
Example
from datetime import datetime quarters_between_dates(datetime(2025, 1, 1), datetime(2025, 10, 1)) 3 quarters_between_dates(datetime(2025, 1, 15), datetime(2025, 4, 14)) 0
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
recurring_dates(start: date, end: date, frequency: Literal['daily', 'weekly', 'biweekly', 'monthly', 'yearly'] = 'monthly', weekday: Optional[int] = None) -> List[date]
¶
Generates recurring dates within a range.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
date
|
First date of the range (inclusive). |
required |
end
|
date
|
Last date of the range (inclusive). |
required |
frequency
|
Literal['daily', 'weekly', 'biweekly', 'monthly', 'yearly']
|
One of |
'monthly'
|
weekday
|
Optional[int]
|
For |
None
|
Returns:
| Type | Description |
|---|---|
List[date]
|
A sorted list of dates matching the recurrence rule. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If start > end or frequency is invalid. |
Example
from datetime import date recurring_dates(date(2026, 1, 1), date(2026, 3, 1), "monthly") [datetime.date(2026, 1, 1), datetime.date(2026, 2, 1), datetime.date(2026, 3, 1)]
Complexity: O(n) where n is the number of occurrences.
Source code in shortfx/fxDate/date_operations.py
5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 | |
relative_time(dt_input: Union[datetime, date], reference: Optional[Union[datetime, date]] = None, lang: str = 'en') -> str
¶
Describe a datetime relative to a reference point.
Produces output like "2 hours ago", "in 3 days",
"hace 2 horas", "en 3 días".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt_input
|
Union[datetime, date]
|
Target date/datetime. |
required |
reference
|
Optional[Union[datetime, date]]
|
Reference point (defaults to now). |
None
|
lang
|
str
|
Language code ( |
'en'
|
Returns:
| Type | Description |
|---|---|
str
|
Human-readable relative time string. |
Example
from datetime import datetime, timedelta ref = datetime(2025, 6, 15, 12, 0, 0) relative_time(ref - timedelta(hours=2), ref) '2 hours ago' relative_time(ref + timedelta(days=3), ref, 'es') 'en 3 días'
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 | |
relative_time_description(dt_value: datetime, reference: Optional[datetime] = None, language: str = 'en') -> str
¶
Returns a human-readable relative time string.
Computes the difference between dt_value and reference and produces
a short description such as "2 hours ago" or "hace 3 dias".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt_value
|
datetime
|
The target datetime. |
required |
reference
|
Optional[datetime]
|
The baseline datetime (defaults to |
None
|
language
|
str
|
|
'en'
|
Returns:
| Type | Description |
|---|---|
str
|
A human-readable relative time string. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If dt_value is not a datetime. |
Example
from datetime import datetime, timedelta ref = datetime(2026, 4, 4, 12, 0) relative_time_description(ref - timedelta(hours=2), ref) '2 hours ago'
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 | |
round_datetime(dt_value: datetime, unit: Literal['minute', 'hour', 'day'] = 'hour') -> datetime
¶
Rounds a datetime to the nearest unit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt_value
|
datetime
|
The datetime to round. |
required |
unit
|
Literal['minute', 'hour', 'day']
|
|
'hour'
|
Returns:
| Type | Description |
|---|---|
datetime
|
The rounded datetime. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If dt_value is not a datetime. |
ValueError
|
If unit is invalid. |
Example
round_datetime(datetime(2026, 4, 4, 14, 35), "hour") datetime.datetime(2026, 4, 4, 15, 0)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
semester(d: Union[datetime, date, str]) -> int
¶
Returns which semester (1 or 2) a date falls in.
Semester 1 = January–June, Semester 2 = July–December.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
Union[datetime, date, str]
|
A date, datetime, or ISO-format string ( |
required |
Returns:
| Type | Description |
|---|---|
int
|
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If the argument is not a valid date type. |
Example
from datetime import date semester(date(2024, 3, 15)) 1
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
set_date_component(date_input: datetime, **kwargs: Any) -> datetime
¶
Returns a new datetime object with specified components modified.
Problem/User Need: Users often need to modify only a part of an existing date without affecting the others (e.g., change only the day to 15, or set the time to 00:00:00).
Product Goals: Offer granular and flexible date manipulation, useful for date editing scenarios or precise normalization.
Description: Given an existing datetime object, this function returns a new datetime
object where the components specified in kwargs (e.g., 'year', 'month', 'day',
'hour', 'minute', 'second', 'microsecond', 'tzinfo') have been updated.
All other components remain unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The original datetime object to modify. |
required |
**kwargs
|
Any
|
Keyword arguments corresponding to datetime components you want to change. Valid keywords are 'year', 'month', 'day', 'hour', 'minute', 'second', 'microsecond', and 'tzinfo'. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
A new datetime object with the specified components updated. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'date_input' is not a datetime object. |
ValueError
|
If any provided keyword argument is not a valid datetime component or if its value is out of the valid range (e.g., month=13). |
Example
from datetime import datetime, timezone
Original date¶
original_date = datetime(2025, 6, 11, 15, 30, 45, 123456) print(f"Original: {original_date}") Original: 2025-06-11 15:30:45.123456
Change only the day to 1¶
set_date_component(original_date, day=1) datetime.datetime(2025, 6, 1, 15, 30, 45, 123456)
Set hour, minute, second to midnight (00:00:00)¶
set_date_component(original_date, hour=0, minute=0, second=0, microsecond=0) datetime.datetime(2025, 6, 11, 0, 0, 0, 0)
Change year and timezone¶
set_date_component(original_date, year=2026, tzinfo=timezone.utc) datetime.datetime(2026, 6, 11, 15, 30, 45, 123456, tzinfo=datetime.timezone.utc)
Invalid component will raise an error¶
try: set_date_component(original_date, invalid_param=10) except TypeError as e: print(f"Error: {e}")
Expected output: Error: 'invalid_param' is an invalid keyword argument for this method.¶
Cost: O(1), constant time for creating new datetime with modified components.
Source code in shortfx/fxDate/date_operations.py
1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 | |
set_microseconds(date_input: datetime, microseconds: int) -> datetime
¶
Devuelve un nuevo objeto datetime con los microsegundos establecidos al valor especificado.
Problema/Necesidad del Usuario: A veces, se necesita establecer los microsegundos de un datetime a un valor exacto, sin afectar los otros componentes de tiempo.
Objetivos del Producto: Ofrecer control total sobre la granularidad de microsegundos, útil para normalización o para establecer valores precisos.
Descripción: Esta función toma un objeto datetime y un entero para los microsegundos.
Crea y devuelve un nuevo objeto datetime donde solo la parte de los microsegundos
ha sido modificada al valor proporcionado, manteniendo el año, mes, día, hora,
minuto, segundo y zona horaria (si existe) del objeto original.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
El objeto |
required |
microseconds
|
int
|
El valor de microsegundos a establecer (de 0 a 999999). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
Un nuevo objeto |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'date_input' no es un objeto |
ValueError
|
Si 'microseconds' está fuera del rango válido (0 a 999999). |
Example
from datetime import datetime
Ejemplo 1: Establecer microsegundos a un valor específico¶
dt = datetime(2025, 6, 11, 10, 0, 0, 123456) set_microseconds(dt, 789) datetime.datetime(2025, 6, 11, 10, 0, 0, 789)
Ejemplo 2: Establecer microsegundos a cero¶
dt = datetime(2025, 6, 11, 10, 0, 0, 987654) set_microseconds(dt, 0) datetime.datetime(2025, 6, 11, 10, 0, 0, 0)
Ejemplo 3: Valor de microsegundos fuera de rango (levantará ValueError)¶
try: set_microseconds(datetime(2025, 6, 11, 10, 0, 0), 1000000) except ValueError as e: print(f"Error: {e}")
Expected output: Error: microseconds must be in 0..999999¶
Source code in shortfx/fxDate/date_operations.py
shift_schedule(start_date: Union[date, datetime], shift_days: int, rest_days: int, target_date: Union[date, datetime]) -> str
¶
Determines if a target date is a work or rest day in a cyclic rotation.
Models a rotating shift pattern like "4 days on, 2 days off" starting from start_date.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
Union[date, datetime]
|
First day of the first shift cycle. |
required |
shift_days
|
int
|
Number of consecutive working days per cycle. |
required |
rest_days
|
int
|
Number of consecutive rest days per cycle. |
required |
target_date
|
Union[date, datetime]
|
The date to evaluate. |
required |
Returns:
| Type | Description |
|---|---|
str
|
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If dates or integers have wrong types. |
ValueError
|
If shift_days or rest_days are not positive. |
Example
from datetime import date shift_schedule(date(2026, 1, 1), 4, 2, date(2026, 1, 5)) 'work' shift_schedule(date(2026, 1, 1), 4, 2, date(2026, 1, 6)) 'rest'
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
snap_to_weekday(date_input: Union[datetime, date], target_weekday: int, direction: str = 'next') -> Union[datetime, date]
¶
Snap a date to the nearest specified weekday.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Union[datetime, date]
|
Starting date. |
required |
target_weekday
|
int
|
Target weekday (0=Monday … 6=Sunday). |
required |
direction
|
str
|
|
'next'
|
Returns:
| Type | Description |
|---|---|
Union[datetime, date]
|
Date snapped to the target weekday (same type as input). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If target_weekday is not in [0, 6] or direction is invalid. |
Example
from datetime import date snap_to_weekday(date(2025, 6, 11), 0) datetime.date(2025, 6, 16) snap_to_weekday(date(2025, 6, 11), 0, 'previous') datetime.date(2025, 6, 9)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
start_of_month(date_input: Union[datetime, str], input_format: str = None) -> datetime
¶
Returns a datetime object representing the first day of the month for a given date.
Problem/User Need: When dealing with monthly reports, billing cycles, or any month-based aggregation, it's often necessary to precisely define the start of the month.
Product Goals: Simplify business logic and data aggregation for monthly periods.
Description: Given a date (as a datetime object or a string with a specified format), this function returns a new datetime object set to the 1st day of that date's month, at 00:00:00.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Union[datetime, str]
|
The date for which to get the start of the month. Can be a datetime object (e.g., datetime(2023, 10, 15)) or a string (e.g., "15/10/2023"). |
required |
input_format
|
str
|
The format code string for 'date_input' if it's a string. Required if 'date_input' is a string. E.g., '%d/%m/%Y' for "15/10/2023". Not used if 'date_input' is a datetime object. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
A new datetime object representing the 1st day of the month, at midnight. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'date_input' is not a datetime object or a string. |
ValueError
|
If 'date_input' is a string and 'input_format' is not provided, or if the string cannot be parsed with the given format. |
Example
from datetime import datetime
Using a datetime object in the middle of a month¶
start_of_month(datetime(2023, 10, 15, 10, 30, 0)) datetime.datetime(2023, 10, 1, 0, 0)
Using a string input¶
start_of_month("25-11-2024", "%d-%m-%Y") datetime.datetime(2024, 11, 1, 0, 0)
Cost: O(1), constant time for date manipulation.
Source code in shortfx/fxDate/date_operations.py
start_of_quarter(date_input: Union[datetime, str], input_format: Optional[str] = None) -> datetime
¶
Returns the first day of the quarter for a given date.
Description
Determines which quarter the date belongs to and returns the first day of that quarter at 00:00:00.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Union[datetime, str]
|
The date for which to get the start of the quarter. |
required |
input_format
|
Optional[str]
|
Format string if date_input is a string. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
First day of the quarter at midnight. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If date_input is not a datetime or string. |
ValueError
|
If date_input is a string and input_format is not provided. |
Example
from datetime import datetime start_of_quarter(datetime(2026, 8, 15)) datetime.datetime(2026, 7, 1, 0, 0) start_of_quarter(datetime(2026, 1, 20)) datetime.datetime(2026, 1, 1, 0, 0)
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
start_of_year(date_input: Union[datetime, str], input_format: str = None) -> datetime
¶
Returns a datetime object representing the first day of the year for a given date.
Problem/User Need: Similar to months, annual reports and planning require an easy way to get the first day of a year.
Product Goals: Support annual analysis and reporting functionality.
Description: Given a date (as a datetime object or a string with a specified format), this function returns a new datetime object set to January 1st of the year to which that date belongs, at 00:00:00.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
Union[datetime, str]
|
The date for which to get the start of the year. Can be a datetime object (e.g., datetime(2023, 7, 20)) or a string (e.g., "20/07/2023"). |
required |
input_format
|
str
|
The format code string for 'date_input' if it's a string. Required if 'date_input' is a string. E.g., '%d/%m/%Y' for "20/07/2023". Not used if 'date_input' is a datetime object. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
A new datetime object representing January 1st of the year, at midnight. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'date_input' is not a datetime object or a string. |
ValueError
|
If 'date_input' is a string and 'input_format' is not provided, or if the string cannot be parsed with the given format. |
Example
from datetime import datetime
Using a datetime object¶
start_of_year(datetime(2023, 7, 20)) datetime.datetime(2023, 1, 1, 0, 0)
Using a string input¶
start_of_year("15-03-2024", "%d-%m-%Y") datetime.datetime(2024, 1, 1, 0, 0)
Cost: O(1), constant time for date manipulation.
Source code in shortfx/fxDate/date_operations.py
sunrise_sunset(latitude: float, longitude: float, d: Union[date, datetime]) -> Tuple
¶
Approximate sunrise and sunset times for a location (UTC).
Uses the NOAA simplified solar equations. Accuracy is typically within a few minutes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
latitude
|
float
|
Latitude in decimal degrees (positive North). |
required |
longitude
|
float
|
Longitude in decimal degrees (positive East). |
required |
d
|
Union[date, datetime]
|
The date for calculation. |
required |
Returns:
| Type | Description |
|---|---|
Tuple
|
Tuple of (sunrise, sunset) as datetime objects in UTC. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If inputs have wrong types. |
ValueError
|
If latitude or longitude is out of range. |
Example
from datetime import date sr, ss = sunrise_sunset(40.4168, -3.7038, date(2026, 6, 21)) sr.hour # ~5 UTC for Madrid summer 5
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 | |
time_difference(start_date: datetime | str | date, end_date: datetime | str | date, unit: str = 'days') -> float
¶
Calculates the difference between two dates in a specified unit of time.
Description
This function takes two dates, which can be datetime objects, date objects,
or str representations, and calculates the difference between them
in the specified unit (e.g., 'days', 'hours', 'minutes'). It uses the
string_to_date helper function to parse string inputs intelligently,
converting date objects to datetime objects at the start of the day
(00:00:00) for consistent calculations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime | str | date
|
The starting date. This can be a
|
required |
end_date
|
datetime | str | date
|
The ending date. This can be a
|
required |
unit
|
str
|
The unit of time for the difference. Valid units are: 'microseconds', 'milliseconds', 'seconds', 'minutes', 'hours', 'days', 'weeks'. Defaults to 'days'. |
'days'
|
Returns:
| Name | Type | Description |
|---|---|---|
float |
float
|
The numerical difference between the two dates in the specified unit (can be negative if start_date > end_date). The return type is float to allow for fractional differences (e.g., 1.5 hours). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
ValueError
|
If |
Example of use
from datetime import datetime, date date1 = datetime(2023, 1, 1, 10, 0, 0) date2 = datetime(2023, 1, 1, 12, 30, 0) time_difference(date1, date2, 'minutes') 150.0 time_difference("2023-01-01", "2023-01-10", 'days') 9.0 time_difference("2023-01-01 10:00:00", "2023-01-02 11:00:00", 'hours') 25.0 time_difference(date(2023, 5, 1), date(2023, 4, 25), 'days') -6.0 time_difference("2023-01-01 00:00:00", "2023-01-01 00:00:01.5", 'milliseconds') 1500.0
Cost: O(1), constant time for date subtraction and conversion.
Source code in shortfx/fxDate/date_operations.py
1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 | |
time_from_datetime(datetime_object: datetime) -> time
¶
Extracts the time component from a datetime object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datetime_object
|
datetime
|
The datetime object from which to extract the time. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
time |
time
|
A time object representing the hour, minute, second, and microsecond of the input datetime object. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'datetime_object' is not a datetime object. |
Example
from datetime import datetime, time my_datetime = datetime(2023, 10, 26, 15, 30, 45, 123456) time_from_datetime(my_datetime) datetime.time(15, 30, 45, 123456) time_from_datetime(datetime(2024, 1, 1, 9, 0, 0)) datetime.time(9, 0)
Cost: O(1), constant time for extracting time component.
Source code in shortfx/fxDate/date_operations.py
time_overlap(start1: datetime, end1: datetime, start2: datetime, end2: datetime) -> float
¶
Return overlapping seconds between two time intervals.
If the intervals do not overlap, returns 0.0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start1
|
datetime
|
Start of first interval. |
required |
end1
|
datetime
|
End of first interval. |
required |
start2
|
datetime
|
Start of second interval. |
required |
end2
|
datetime
|
End of second interval. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Overlap duration in seconds. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If arguments are not datetime instances. |
Example
from datetime import datetime a, b = datetime(2026, 1, 1, 8, 0), datetime(2026, 1, 1, 12, 0) c, d = datetime(2026, 1, 1, 10, 0), datetime(2026, 1, 1, 14, 0) time_overlap(a, b, c, d) 7200.0
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
time_zone_abbreviation(tz_name: str, ref: datetime | None = None) -> str
¶
Return the common abbreviation for a timezone at a given moment.
Uses only the standard library zoneinfo (Python 3.9+).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tz_name
|
str
|
IANA timezone name (e.g. |
required |
ref
|
datetime | None
|
Reference datetime. Defaults to now (UTC). |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Timezone abbreviation string (e.g. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If tz_name is not a string. |
ValueError
|
If tz_name is not a recognized timezone. |
Example
time_zone_abbreviation("US/Eastern", datetime(2026, 1, 15)) 'EST'
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
timedelta_to_components(timedelta_obj: timedelta) -> Dict[str, Union[int, float]]
¶
Convierte un objeto timedelta de Python en un diccionario con sus componentes.
Problema/Necesidad del Usuario: Cuando calculamos diferencias entre fechas, obtenemos un objeto timedelta. A menudo, los usuarios necesitan desglosar este timedelta en componentes más legibles (días, horas, minutos, segundos) para mostrarlos en la UI o para realizar cálculos adicionales.
Objetivos del Producto: Mejorar la legibilidad y la manipulación de los resultados de diferencias de tiempo, haciéndolos más accesibles para la presentación al usuario o para la lógica de negocio.
Descripción: Dada un objeto timedelta, esta función lo descompone en
días, las horas restantes, los minutos restantes, los segundos restantes,
y los microsegundos restantes, y los devuelve en un diccionario. La función
maneja correctamente los timedelta positivos y negativos, aplicando el
signo correspondiente a cada componente.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
timedelta_obj
|
timedelta
|
El objeto |
required |
Returns:
| Type | Description |
|---|---|
Dict[str, Union[int, float]]
|
Dict[str, Union[int, float]]: Un diccionario con las claves:
'days', 'hours', 'minutes', 'seconds', 'microseconds'.
Todos los valores son enteros y reflejan el signo
general del |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si 'timedelta_obj' no es un objeto |
Example
Ejemplo 1: Diferencia positiva (1 día, 1 hora, 30 minutos)¶
dt_future = datetime(2025, 6, 12, 10, 0, 0) dt_past = datetime(2025, 6, 11, 8, 30, 0) td_positive = dt_future - dt_past # Esto resulta en timedelta(days=1, seconds=5400) timedelta_to_components(td_positive)
Ejemplo 2: Diferencia negativa (1 día, 1 hora, 30 minutos antes)¶
td_negative = dt_past - dt_future # Esto es -1 día, -1 hora, -30 minutos timedelta_to_components(td_negative)
Ejemplo 3: Solo segundos y microsegundos¶
td_small = timedelta(seconds=123, microseconds=456789) timedelta_to_components(td_small)
Ejemplo 4: Un timedelta con microsegundos exactos¶
td_micro = timedelta(microseconds=500) timedelta_to_components(td_micro)
Ejemplo 5: Entrada inválida (levantará TypeError)¶
try: timedelta_to_components("5 days") except TypeError as e: print(f"Error: {e}")
Expected output: Error: Input 'timedelta_obj' must be a datetime.timedelta object.¶
Source code in shortfx/fxDate/date_operations.py
3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 | |
trading_days_between(start: date | datetime, end: date | datetime, holidays: list[date] | None = None, weekend: tuple[int, ...] = (5, 6)) -> int
¶
Count trading days between two dates.
Similar to :func:business_days_between but allows a configurable
weekend tuple, making it suitable for markets that trade on
Saturdays or close on Sundays/Fridays.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
date | datetime
|
Start date (inclusive). |
required |
end
|
date | datetime
|
End date (exclusive). |
required |
holidays
|
list[date] | None
|
Optional market holidays to exclude. |
None
|
weekend
|
tuple[int, ...]
|
Weekday numbers considered non-trading (Mon=0). |
(5, 6)
|
Returns:
| Type | Description |
|---|---|
int
|
Number of trading days. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If start or end are not date/datetime. |
Example
from datetime import date trading_days_between(date(2026, 4, 6), date(2026, 4, 13)) 5
Complexity: O(d), d = days between start and end.
Source code in shortfx/fxDate/date_operations.py
week_number(date_input: datetime, system: int = 1) -> int
¶
Returns the week number of the year for a given date.
Description
Standalone convenience function to get the week number. Supports two systems: week starting on Sunday (system 1) or ISO standard (system 21, week starting on Monday with ISO rules).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The date to evaluate. |
required |
system
|
int
|
1 = week begins on Sunday (default), 21 = ISO week number. |
1
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Week number (1-53). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If date_input is not a datetime object. |
ValueError
|
If system is not 1 or 21. |
Example
from datetime import datetime week_number(datetime(2025, 1, 1)) 1 week_number(datetime(2025, 1, 1), system=21) 1
Complexity: O(1)
Source code in shortfx/fxDate/date_operations.py
week_of_month(date_input: datetime, start_of_week: int = 0) -> int
¶
Devuelve el número de la semana del mes para una fecha dada.
Problema/Necesidad del Usuario: Determinar la semana del mes es útil para la planificación mensual, la generación de informes o la organización de eventos recurrentes.
Objetivos del Producto: Proporcionar una forma sencilla de identificar la semana del mes, con la flexibilidad de definir el día de inicio de la semana.
Descripción: Esta función calcula el número de la semana del mes para date_input.
La semana 1 comienza con el primer día del mes. Las semanas subsiguientes se cuentan
basándose en el start_of_week especificado. Por defecto, start_of_week es 0 (lunes).
Es decir, si el primer día del mes es un miércoles y start_of_week es lunes,
la semana 1 incluirá ese miércoles y la semana 2 comenzará el primer lunes completo
después del día 1 del mes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
La fecha para la cual se desea obtener el número de semana del mes. |
required |
start_of_week
|
int
|
El día en que comienza la semana (0=Lunes, 6=Domingo). Por defecto es 0 (Lunes). |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
El número de la semana del mes (1-5 o 1-6, dependiendo de la configuración y el mes). |
Raises:
| Type | Description |
|---|---|
TypeError
|
Si |
ValueError
|
Si |
Example
from datetime import datetime
Ejemplo 1: Fecha en medio del mes (Lunes como inicio de semana por defecto)¶
week_of_month(datetime(2025, 6, 11)) # 11 de junio de 2025 es miércoles 2 # La semana 1 comienza el 1 de junio (domingo), la semana 2 el 2 de junio (lunes).
Ejemplo 2: Principio de mes (Lunes como inicio de semana)¶
week_of_month(datetime(2025, 6, 1)) # 1 de junio de 2025 es domingo 1
Ejemplo 3: Final de mes (Lunes como inicio de semana)¶
week_of_month(datetime(2025, 6, 30)) # 30 de junio de 2025 es lunes 5
Ejemplo 4: Configurando el Domingo como inicio de semana¶
week_of_month(datetime(2025, 6, 11), start_of_week=6) # 11 de junio de 2025 es miércoles 3 # La semana 1 comienza el 1 de junio (domingo), la semana 2 el 8 de junio (domingo).
Ejemplo 5: Tipo de dato incorrecto¶
try: week_of_month("not a date") except TypeError as e: print(f"Error: {e}")
Salida esperada: Error: date_input must be a datetime object.¶
Ejemplo 6: start_of_week fuera de rango¶
try: week_of_month(datetime(2025, 1, 1), start_of_week=7) except ValueError as e: print(f"Error: {e}")
Salida esperada: Error: start_of_week must be an integer between 0 (Monday) and 6 (Sunday).¶
Source code in shortfx/fxDate/date_operations.py
4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 | |
weekday_name(date_input: datetime, language: str = 'en') -> str
¶
Gets the name of the day of the week for a given date in the specified language.
This function leverages your operating system's installed locales to provide weekday names in various languages. The availability of a specific language (locale) depends entirely on what is configured and installed on your operating system. For example, 'es' for Spanish, 'fr' for French, 'de' for German, etc.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The datetime object for which to get the weekday name. |
required |
language
|
str
|
The two-letter ISO 639-1 language code (e.g., 'en', 'es', 'fr', 'de'). Defaults to 'en'. |
'en'
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
The full name of the day of the week (e.g., 'Thursday', 'Jueves', 'Donnerstag'). Note: Capitalization might vary based on the specific locale installed on your system. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'date_input' is not a datetime object. |
ValueError
|
If the specified 'language' cannot be set as a locale on your system. This usually means the corresponding language pack is not installed or the locale name is not recognized by your OS. |
Example
from datetime import datetime date_to_check = datetime(2023, 10, 26) # A Thursday
Example for English (always available)¶
weekday_name(date_to_check, 'en') 'Thursday'
Example for Spanish (requires 'es' or 'es_ES.UTF-8' locale installed on your system)¶
try: weekday_name(date_to_check, 'es') except ValueError as e: print(f"Could not get Spanish weekday name: {e}")
Expected output (if locale installed): 'jueves' or 'Jueves'¶
Example for German (requires 'de' or 'de_DE.UTF-8' locale installed on your system)¶
try: weekday_name(date_to_check, 'de') except ValueError as e: print(f"Could not get German weekday name: {e}")
Expected output (if locale installed): 'Donnerstag'¶
Cost: O(1), constant time for locale operations and string formatting.
Source code in shortfx/fxDate/date_operations.py
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | |
weekday_number(date_input: datetime, start_day: str = 'european') -> int
¶
Retrieves the day of the week as a number for a given date, supporting both European (Monday=0) and US (Sunday=0) conventions.
This function leverages the datetime.weekday() method, which by default
returns Monday as 0 and Sunday as 6. It then adjusts this value if the
'anglo' convention is specified to ensure Sunday is 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
date_input
|
datetime
|
The date for which to get the weekday number. |
required |
start_day
|
str
|
Specifies the starting day convention. Accepted values are 'european' (Monday=0) or 'anglo' (Sunday=0). Defaults to 'european'. |
'european'
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The day of the week as an integer (e.g., 0 for Monday in 'european', 0 for Sunday in 'anglo'). |
Raises:
| Type | Description |
|---|---|
TypeError
|
If 'date_input' is not a datetime object. |
ValueError
|
If 'start_day' is not 'european' or 'anglo'. |
Example
from datetime import datetime date_to_check_thursday = datetime(2023, 10, 26) # A Thursday weekday_number(date_to_check_thursday, start_day='european') 3 weekday_number(date_to_check_thursday, start_day='anglo') 4 date_to_check_sunday = datetime(2023, 10, 29) # A Sunday weekday_number(date_to_check_sunday, start_day='european') 6 weekday_number(date_to_check_sunday, start_day='anglo') 0
Cost: O(1), constant time for date arithmetic operations.
Source code in shortfx/fxDate/date_operations.py
workday(start_date: datetime, days: int, holidays: Optional[List[datetime]] = None) -> datetime
¶
Returns the date after a given number of working days (Mon-Fri).
Description
Starting from start_date, counts forward (positive days) or backward (negative days), skipping weekends (Saturday/Sunday) and optional holidays. The start_date itself is not counted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime
|
The starting date. |
required |
days
|
int
|
Number of working days to advance (positive) or go back (negative). |
required |
holidays
|
Optional[List[datetime]]
|
Optional list of holiday datetimes to skip. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
The resulting date after the specified working days. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If start_date is not a datetime or days is not an int. |
Example
from datetime import datetime workday(datetime(2025, 1, 6), 5) # Mon + 5 working days = Mon datetime.datetime(2025, 1, 13, 0, 0) workday(datetime(2025, 1, 6), -1) datetime.datetime(2025, 1, 3, 0, 0)
Complexity: O(n) where n is abs(days)
Source code in shortfx/fxDate/date_operations.py
workday_intl(start_date: datetime, days: int, weekend: Union[int, str] = 1, holidays: Optional[List[datetime]] = None) -> datetime
¶
Returns the date after a given number of working days with custom weekends.
Description
Like workday but allows specifying which days count as weekends via the same convention as network_days_intl.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime
|
The starting date. |
required |
days
|
int
|
Number of working days to advance (positive) or go back (negative). |
required |
weekend
|
Union[int, str]
|
Weekend definition (see network_days_intl for details). |
1
|
holidays
|
Optional[List[datetime]]
|
Optional list of holiday datetimes to skip. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
datetime |
datetime
|
The resulting date. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If start_date is not a datetime or days is not an int. |
Example
from datetime import datetime workday_intl(datetime(2025, 1, 6), 5, weekend=2) datetime.datetime(2025, 1, 14, 0, 0)
Complexity: O(n) where n is abs(days)
Source code in shortfx/fxDate/date_operations.py
working_hours_in_month(year: int, month: int, hours_per_day: float = 8.0, holidays: list[date] | None = None) -> float
¶
Calculate total working hours in a given month.
Counts weekdays (Mon-Fri) excluding holidays, then multiplies by hours_per_day.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
year
|
int
|
Calendar year. |
required |
month
|
int
|
Calendar month (1-12). |
required |
hours_per_day
|
float
|
Working hours per business day. |
8.0
|
holidays
|
list[date] | None
|
Optional list of holidays to exclude. |
None
|
Returns:
| Type | Description |
|---|---|
float
|
Total working hours as a float. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If arguments have wrong types. |
ValueError
|
If month is outside [1, 12]. |
Example
working_hours_in_month(2026, 1) 176.0
Complexity: O(d), d = days in month.
Source code in shortfx/fxDate/date_operations.py
year_fraction(start_date: datetime, end_date: datetime, basis: int = 0) -> float
¶
Calculates the fraction of year between two dates.
Description
Useful for financial calculations such as bond accrued interest or prorated payments. Supports two day-count conventions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
datetime
|
The start date. |
required |
end_date
|
datetime
|
The end date. |
required |
basis
|
int
|
Day-count basis. 0 = US 30/360 (default), 1 = Actual/Actual. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
float |
float
|
Fraction of the year between the dates. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If dates are not datetime objects. |
ValueError
|
If basis is not 0 or 1. |
Example
from datetime import datetime year_fraction(datetime(2025, 1, 1), datetime(2025, 7, 1), basis=0) 0.5 year_fraction(datetime(2025, 1, 1), datetime(2025, 7, 1), basis=1) 0.4958904109589041
Complexity: O(1)