0
# Relative Date Calculations
1
2
Advanced date arithmetic supporting both relative operations (add/subtract time periods) and absolute operations (set specific date components). Handles complex scenarios like month-end dates, leap years, and weekday calculations intelligently.
3
4
## Capabilities
5
6
### relativedelta Class
7
8
The core class for relative date calculations, supporting both relative and absolute date operations in a single interface.
9
10
```python { .api }
11
class relativedelta:
12
def __init__(self, dt1=None, dt2=None,
13
years=0, months=0, days=0, leapdays=0, weeks=0,
14
hours=0, minutes=0, seconds=0, microseconds=0,
15
year=None, month=None, day=None, weekday=None,
16
yearday=None, nlyearday=None,
17
hour=None, minute=None, second=None, microsecond=None):
18
"""
19
Create a relativedelta instance for date calculations.
20
21
Parameters:
22
- dt1, dt2 (datetime, optional): Create relativedelta from difference between two datetimes
23
- Relative parameters (plural): years, months, days, weeks, hours, minutes, seconds, microseconds, leapdays
24
- Absolute parameters (singular): year, month, day, hour, minute, second, microsecond
25
- weekday (weekday instance): Weekday specification (MO, TU, etc.)
26
- yearday (int): Day of year (1-366)
27
- nlyearday (int): Day of non-leap year (1-365)
28
"""
29
30
def normalized(self):
31
"""
32
Return a relativedelta with normalized relative components.
33
34
Returns:
35
relativedelta: New instance with integer relative attributes
36
"""
37
38
@property
39
def weeks(self):
40
"""Get/set weeks property."""
41
```
42
43
**Usage Examples:**
44
45
```python
46
from dateutil.relativedelta import relativedelta
47
from datetime import datetime
48
49
# Relative operations (add/subtract)
50
dt = datetime(2023, 1, 31)
51
next_month = dt + relativedelta(months=1) # Feb 28, 2023
52
next_year = dt + relativedelta(years=1) # Jan 31, 2024
53
54
# Absolute operations (replace)
55
new_year = dt + relativedelta(month=1, day=1) # Jan 1, 2023
56
midnight = dt + relativedelta(hour=0, minute=0, second=0)
57
58
# Mixed operations
59
first_friday = dt + relativedelta(day=1, weekday=4) # First Friday of month
60
61
# From two datetimes
62
dt1 = datetime(2023, 12, 25)
63
dt2 = datetime(2024, 1, 15)
64
delta = relativedelta(dt2, dt1) # Difference between dates
65
```
66
67
### Weekday Constants
68
69
Predefined weekday instances for use in relativedelta calculations, supporting nth weekday specifications.
70
71
```python { .api }
72
# Weekday constants (Monday=0 to Sunday=6)
73
MO = weekday(0)
74
TU = weekday(1)
75
WE = weekday(2)
76
TH = weekday(3)
77
FR = weekday(4)
78
SA = weekday(5)
79
SU = weekday(6)
80
81
class weekday:
82
def __init__(self, wkday, n=None):
83
"""
84
Weekday specification for relativedelta.
85
86
Parameters:
87
- wkday (int): Weekday number (0=Monday, 6=Sunday)
88
- n (int, optional): Nth occurrence (+1 for next, -1 for previous)
89
"""
90
```
91
92
**Usage Examples:**
93
94
```python
95
from dateutil.relativedelta import relativedelta, MO, FR
96
from datetime import datetime
97
98
dt = datetime(2023, 6, 15) # Thursday
99
100
# Next Friday
101
next_fri = dt + relativedelta(weekday=FR) # June 16, 2023
102
next_fri_2 = dt + relativedelta(weekday=FR(1)) # Same as above
103
104
# Previous Friday
105
prev_fri = dt + relativedelta(weekday=FR(-1)) # June 9, 2023
106
107
# First Monday of next month
108
first_mon = dt + relativedelta(months=1, day=1, weekday=MO)
109
110
# Last Friday of current month
111
last_fri = dt + relativedelta(day=31, weekday=FR(-1))
112
```
113
114
### Arithmetic Operations
115
116
relativedelta supports all standard arithmetic operations for combining and manipulating date deltas.
117
118
```python { .api }
119
# Addition and subtraction
120
def __add__(self, other): ... # relativedelta + datetime/relativedelta
121
def __radd__(self, other): ... # datetime + relativedelta
122
def __sub__(self, other): ... # relativedelta - relativedelta
123
def __rsub__(self, other): ... # datetime - relativedelta
124
125
# Multiplication and division
126
def __mul__(self, other): ... # relativedelta * number
127
def __rmul__(self, other): ... # number * relativedelta
128
def __div__(self, other): ... # relativedelta / number (Python 2)
129
def __truediv__(self, other): ... # relativedelta / number (Python 3)
130
131
# Unary operations
132
def __neg__(self): ... # -relativedelta
133
def __abs__(self): ... # abs(relativedelta)
134
135
# Comparison operations
136
def __eq__(self, other): ... # relativedelta == relativedelta
137
def __ne__(self, other): ... # relativedelta != relativedelta
138
def __hash__(self): ... # hash(relativedelta)
139
140
# Boolean operations
141
def __bool__(self): ... # bool(relativedelta) - Python 3
142
def __nonzero__(self): ... # bool(relativedelta) - Python 2
143
```
144
145
**Usage Examples:**
146
147
```python
148
from dateutil.relativedelta import relativedelta
149
from datetime import datetime
150
151
# Combining relativedeltas
152
delta1 = relativedelta(months=1, days=5)
153
delta2 = relativedelta(weeks=2, hours=3)
154
combined = delta1 + delta2
155
156
# Multiplying deltas
157
double_delta = delta1 * 2
158
half_delta = delta1 / 2
159
160
# Boolean testing
161
if delta1: # True if any non-zero components
162
print("Delta has non-zero components")
163
164
# Comparison
165
if delta1 == delta2:
166
print("Deltas are equal")
167
```
168
169
## Common Patterns
170
171
### Month-End Date Handling
172
173
```python
174
from dateutil.relativedelta import relativedelta
175
from datetime import datetime
176
177
# Safe month arithmetic for month-end dates
178
jan_31 = datetime(2023, 1, 31)
179
feb_end = jan_31 + relativedelta(months=1) # Feb 28, 2023 (not March 3rd)
180
mar_end = feb_end + relativedelta(months=1) # Mar 28, 2023
181
182
# Get last day of month
183
last_day = datetime(2023, 6, 1) + relativedelta(months=1, days=-1) # June 30
184
```
185
186
### Recurring Date Calculations
187
188
```python
189
from dateutil.relativedelta import relativedelta, MO
190
from datetime import datetime
191
192
start_date = datetime(2023, 1, 1)
193
194
# Every 3rd Monday of each month for a year
195
third_mondays = []
196
for month in range(12):
197
third_monday = start_date + relativedelta(months=month, day=1, weekday=MO(3))
198
third_mondays.append(third_monday)
199
200
# Quarterly dates
201
quarterly = [start_date + relativedelta(months=3*i) for i in range(4)]
202
```
203
204
## Types
205
206
```python { .api }
207
class relativedelta:
208
# Instance attributes (read-only after construction)
209
years: int
210
months: int
211
days: int
212
leapdays: int
213
hours: int
214
minutes: int
215
seconds: int
216
microseconds: int
217
year: int | None
218
month: int | None
219
day: int | None
220
weekday: weekday | None
221
hour: int | None
222
minute: int | None
223
second: int | None
224
microsecond: int | None
225
226
class weekday:
227
weekday: int # 0-6 (Monday-Sunday)
228
n: int | None # Nth occurrence
229
```