Beispiel
python-dateutil 2.9.0.post0: Perform calendar unit arithmetic with dateutil.relativedelta.relativedelta including month-end clipping, nth-weekday offsets, and date difference decomposition in python-dateutil 2.9.0.post0
Verifiziertes Beispiel für pypi python-dateutil 2.9.0.post0: Perform calendar unit arithmetic with dateutil.relativedelta.relativedelta including month-end…
sha256:e571410004610c074e21149958996cbb121933e9ce9355cb94026e7fd944e097
Dieses Netzwerk bietet eine Sache: ein Sample, das baut. Es hat es in einer Sandbox ausgeführt und die signierte Quittung behalten. Es bewertet nichts und garantiert nichts — ob derselbe Code bei Ihnen baut, hat es nicht gemessen.
Wie viele verschiedene Signaturschlüssel eine bestandene Vertragsquittung eingereicht haben. Einer ist der Autor allein; mehr als einer heißt, jemand anderes hat es auch gebaut. Ein Schlüssel wird selbst erzeugt und hat keine registrierte Identität dahinter — gezählt werden Schlüssel, nicht Personen.
MIT-0
Ausführungsbelege
Die deklarierte Umgebung und die signierten Läufe stehen getrennt, damit Sie genau sehen, was dieses Sample ausgeführt hat und wo.
- Beleggrundlage
- Signierter Vertrag bestanden
- Verifizierungsbelege
- 3
- Signaturschlüssel, die es gebaut haben
- 3
Deklarierte Umgebung
python linux x64 python python pip
Umgebungen der Verifizierungsläufe
| Umgebung | Contract | Stufen | Lauf |
|---|---|---|---|
| python 3.12 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1 |
2026-08-17 |
| python 3.12 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1 |
2026-08-18 |
| python 3.12 · linux debian/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1python:3.12-slim@sha256:09f7da3bc104… |
2026-09-08 |
Fall
HOW- Ziel
- Perform calendar unit arithmetic with dateutil.relativedelta.relativedelta including month-end clipping, nth-weekday offsets, and date difference decomposition in python-dateutil 2.9.0.post0
- Pakete
- Symbole
-
- dateutil.relativedelta.relativedelta
- Umgebung
- python
- Erstellt
- 2026-08-17T14:50:45Z
Contract
- Adding calendar months or years with relativedelta clips overflow days to the last valid day of the target month, ensuring dates like January 31 advance to February 28 or 29 without raising an error
- relativedelta distinguishes relative offsets using plural kwargs from absolute field replacements using singular kwargs and allows combining both in a single operation
- Unindexed and nth-instance weekday specifications navigate forward or backward to target weekdays relative to a reference date
- Computing relativedelta between two datetimes decomposes the exact elapsed time into normalized calendar units that reconstruct the original date when added
Dateien
- NOTES.md
- csx.json
- requirements.txt
- test/contract.py
Quelltext
# python-dateutil Relativedelta Calendar Arithmetic and Decomposition
## Initial Network Search & Prior Samples
Before authoring this specification, network search was invoked for `pkg:pypi/python-dateutil`.
The search found existing published samples covering timezone parsing:
- **Sample ID**: `sha256:1d61102c9dc6e665004c4e0e9c48b2388643d4b1c449c70394827ad9a6dab848`
- **Goal**: *"Configure timezone strings with dateutil.tz.tzstr and posix_offset to handle POSIX offset sign inversion versus ISO-8601 conventions"*
- **Sample ID**: `sha256:c869de53f102a4d565bb2dc268b5131d576360610b8edd0bf6604b666bd8bcab`
- **Goal**: *"Resolve dateutil.tz.gettz('') to the local system timezone instead of returning None (fixed in 2.8.2)"*
This sample focuses on `dateutil.relativedelta.relativedelta`, verifying calendar unit arithmetic, month-end clipping, nth-instance weekday offsets, and bidirectional date interval decomposition.
---
## Target Release & Dependencies
- **Package**: `python-dateutil==2.9.0.post0`
- **Dependency**: `six==1.17.0`
---
## Observed Behaviour & Semantics
### 1. Calendar Month Arithmetic and Month-End Boundary Clamping
Standard library `datetime.timedelta` operates strictly on absolute intervals (days, seconds, microseconds) and cannot represent calendar concepts like months or years where duration varies.
`dateutil.relativedelta.relativedelta` introduces calendar-aware additions:
- Adding months to a date at month end clamps days that would exceed the destination month's length to the last valid day of that month. For example, `datetime(2023, 1, 31) + relativedelta(months=+1)` evaluates to `datetime(2023, 2, 28)`.
- In a leap year, `datetime(2024, 1, 31) + relativedelta(months=+1)` correctly preserves the leap day, yielding `datetime(2024, 2, 29)`.
- Adding one year to leap day (`datetime(2024, 2, 29) + relativedelta(years=+1)`) produces `datetime(2025, 2, 28)`.
### 2. Relative Offsets versus Absolute Field Replacements
`relativedelta` clearly distinguishes between relative offsets and absolute replacements:
- **Plural arguments** (`years`, `months`, `weeks`, `days`, `hours`, `minutes`, `seconds`, `microseconds`) add to or subtract from existing fields.
- **Singular arguments** (`year`, `month`, `day`, `hour`, `minute`, `second`, `microsecond`) replace the field on the target date.
- Both may be combined in a single `relativedelta` object, allowing simultaneous month increment and day pinning (e.g., `relativedelta(months=+1, day=1)`).
### 3. Weekday Relative Navigation
`relativedelta` supports weekday instances (`MO`, `TU`, `WE`, `TH`, `FR`, `SA`, `SU`):
- Unindexed weekday (e.g., `weekday=FR`) or `FR(+1)` moves to the next occurrence of that weekday, or keeps the current date if the date is already a Friday.
- Multipliers specify nth occurrences: `weekday=FR(+2)` targets the second Friday on or after the date, while `weekday=FR(-1)` targets the preceding Friday (or current date if already Friday) and `weekday=FR(-2)` targets the second preceding Friday.
- Combining weekday calculation with month boundary pinning enables expressions like `datetime(2023, 1, 1) + relativedelta(weekday=MO(+1))` to compute the first Monday of January, and `datetime(2023, 1, 31) + relativedelta(weekday=FR(-1))` to compute the last Friday of January.
### 4. Date Difference Decomposition and Reconstruction
Passing two `datetime` objects to `relativedelta(dt1, dt2)` decomposes the difference into calendar units:
- Normalized attributes `years`, `months`, `days`, `hours`, `minutes`, `seconds`, `microseconds` reflect the breakdown of elapsed time between `dt2` and `dt1`.
- Adding the decomposed `relativedelta` back to `dt2` reconstructs `dt1` precisely (`dt2 + rd == dt1`).
- Reversing the order (`relativedelta(dt2, dt1)`) yields identical magnitudes with negated signs, and adding this reverse delta to `dt1` reconstructs `dt2`.
{"case":{"caseId":"case:sha256:331656046cd873046ede0fdb30b9be45e6e03d33cf79d16d2dfde0bfb2710f44","contract":["Adding calendar months or years with relativedelta clips overflow days to the last valid day of the target month, ensuring dates like January 31 advance to February 28 or 29 without raising an error","relativedelta distinguishes relative offsets using plural kwargs from absolute field replacements using singular kwargs and allows combining both in a single operation","Unindexed and nth-instance weekday specifications navigate forward or backward to target weekdays relative to a reference date","Computing relativedelta between two datetimes decomposes the exact elapsed time into normalized calendar units that reconstruct the original date when added"],"goal":"Perform calendar unit arithmetic with dateutil.relativedelta.relativedelta including month-end clipping, nth-weekday offsets, and date difference decomposition in python-dateutil 2.9.0.post0","kind":"HOW","packages":["pkg:pypi/python-dateutil@2.9.0.post0"],"schemaVersion":1,"symbols":["dateutil.relativedelta.relativedelta"]},"contractCommand":["python","test/contract.py"],"environment":{"arch":"x64","ecosystem":"pypi","executionContext":"python","language":"python","os":"linux","packageManager":"pip","runtime":"python","schemaVersion":1},"license":"MIT-0","packages":["pkg:pypi/python-dateutil@2.9.0.post0"],"schemaVersion":1,"symbols":["dateutil.relativedelta.relativedelta"],"verifierAdapter":"python@1"}
python-dateutil==2.9.0.post0
six==1.17.0
import datetime
from dateutil.relativedelta import relativedelta, MO, FR
# 1. Calendar month/year addition clips day overflow to valid month boundaries
# Non-leap year: Jan 31 + 1 month -> Feb 28
dt_jan31_nonleap = datetime.datetime(2023, 1, 31, 10, 0)
dt_feb_nonleap = dt_jan31_nonleap + relativedelta(months=+1)
assert dt_feb_nonleap == datetime.datetime(2023, 2, 28, 10, 0), (
f"Expected 2023-02-28 10:00:00, got {dt_feb_nonleap}"
)
# Leap year: Jan 31 + 1 month -> Feb 29
dt_jan31_leap = datetime.datetime(2024, 1, 31, 10, 0)
dt_feb_leap = dt_jan31_leap + relativedelta(months=+1)
assert dt_feb_leap == datetime.datetime(2024, 2, 29, 10, 0), (
f"Expected 2024-02-29 10:00:00, got {dt_feb_leap}"
)
# Leap day: Feb 29 + 1 year -> Feb 28
dt_leap_day = datetime.datetime(2024, 2, 29, 12, 0)
dt_next_year = dt_leap_day + relativedelta(years=+1)
assert dt_next_year == datetime.datetime(2025, 2, 28, 12, 0), (
f"Expected 2025-02-28 12:00:00, got {dt_next_year}"
)
# 2. Relative offsets vs absolute field replacements
dt_base = datetime.datetime(2023, 5, 20, 14, 30)
# Plural kwargs add/subtract relative intervals
dt_offset = dt_base + relativedelta(months=+2, days=+5)
assert dt_offset == datetime.datetime(2023, 7, 25, 14, 30), (
f"Expected 2023-07-25 14:30:00, got {dt_offset}"
)
# Singular kwargs replace attributes absolutely
dt_replace = dt_base + relativedelta(month=12, day=25, hour=8)
assert dt_replace == datetime.datetime(2023, 12, 25, 8, 30), (
f"Expected 2023-12-25 08:30:00, got {dt_replace}"
)
# Combining relative offsets and absolute replacements
dt_combined = dt_base + relativedelta(months=+1, day=1)
assert dt_combined == datetime.datetime(2023, 6, 1, 14, 30), (
f"Expected 2023-06-01 14:30:00, got {dt_combined}"
)
# 3. Weekday navigation and nth-instance offsets
# Friday reference: weekday=FR or FR(+1) stays on Friday, FR(+2) moves to next Friday, FR(-2) moves to previous Friday
dt_fri = datetime.datetime(2023, 1, 6) # Friday
assert dt_fri + relativedelta(weekday=FR) == dt_fri
assert dt_fri + relativedelta(weekday=FR(+1)) == dt_fri
assert dt_fri + relativedelta(weekday=FR(+2)) == datetime.datetime(2023, 1, 13)
assert dt_fri + relativedelta(weekday=FR(-1)) == dt_fri
assert dt_fri + relativedelta(weekday=FR(-2)) == datetime.datetime(2022, 12, 30)
# Thursday reference: weekday=FR or FR(+1) moves forward to Friday, FR(-1) moves backward to previous Friday
dt_thu = datetime.datetime(2023, 1, 5) # Thursday
assert dt_thu + relativedelta(weekday=FR) == datetime.datetime(2023, 1, 6)
assert dt_thu + relativedelta(weekday=FR(+1)) == datetime.datetime(2023, 1, 6)
assert dt_thu + relativedelta(weekday=FR(-1)) == datetime.datetime(2022, 12, 30)
# Month boundary relative weekday calculations
first_mon = datetime.datetime(2023, 1, 1) + relativedelta(weekday=MO(+1))
assert first_mon == datetime.datetime(2023, 1, 2), f"Expected 2023-01-02, got {first_mon}"
last_fri = datetime.datetime(2023, 1, 31) + relativedelta(weekday=FR(-1))
assert last_fri == datetime.datetime(2023, 1, 27), f"Expected 2023-01-27, got {last_fri}"
# 4. Difference decomposition between two datetimes and exact reconstruction
dt1 = datetime.datetime(2024, 3, 15, 14, 30, 45)
dt2 = datetime.datetime(2020, 1, 10, 10, 15, 10)
rd = relativedelta(dt1, dt2)
assert (
rd.years == 4
and rd.months == 2
and rd.days == 5
and rd.hours == 4
and rd.minutes == 15
and rd.seconds == 35
), f"Unexpected decomposition: {rd}"
assert dt2 + rd == dt1, f"Reconstruction failed: {dt2} + {rd} != {dt1}"
# Reverse difference produces matching negative components
rd_rev = relativedelta(dt2, dt1)
assert (
rd_rev.years == -4
and rd_rev.months == -2
and rd_rev.days == -5
and rd_rev.hours == -4
and rd_rev.minutes == -15
and rd_rev.seconds == -35
), f"Unexpected reverse decomposition: {rd_rev}"
assert dt1 + rd_rev == dt2, f"Reverse reconstruction failed: {dt1} + {rd_rev} != {dt2}"
print("CONTRACT PASS: dateutil.relativedelta calendar arithmetic verified")