Tutorial 2: Durations, Month Arithmetic & Sequences

Open inAnthropic

Series: Time Processing Overview | Tutorial 1: Dates | Tutorial 2 | Tutorial 3: Intervals | Tutorial 4: Creative Patterns

What you will learn

By the end of this tutorial you will be able to:

  • Add and subtract durations from dates using date_duration
  • Explain why P90D and P3M produce different results
  • Describe the end-of-month preservation rule and why it matters for finance
  • Generate sequences of dates, months, and numbers with sequence
  • Extract weekdays and ISO week numbers from dates
  • Find minimum and maximum values with range_min / range_max

Prerequisites


Part 1: Duration Arithmetic with date_duration

date_duration(Start, End, Duration) relates three values. It is tri-directional — give it any two and it computes the third.

Step 1: Add days to a date

Step 1: Add 60 days

What date is 60 days after March 31?

Ctrl+Enter to run

What happened: v:deadline is bound to 2025-05-30. The duration P60D means exactly 60 calendar days. The P prefix is ISO 8601 for "period".

Step 2: Compute the duration between two dates

Step 2: Days between dates

How many days from Jan 1 to Apr 1 in 2025?

Ctrl+Enter to run

Result: P90D — that is 31 (Jan) + 28 (Feb, non-leap) + 31 (Mar) = 90 days.

Step 3: Compute the start from end minus duration

Step 3: Subtract duration

What date is 90 days before April 1?

Ctrl+Enter to run

Step 4: Validate a relationship

When all three arguments are ground, date_duration acts as a validator — it succeeds only if the relationship is correct:

Step 4: Validate — correct

Is it really 90 days from Jan 1 to Apr 1? Succeeds if yes.

Ctrl+Enter to run

Now try changing P90D to P89D — it will return zero results because the relationship is wrong.


Part 2: Why P90D and P3M Are Different

This is the most important concept in this tutorial. Day durations are exact. Month durations are calendar-relative.

Step 5: Day-based duration

Step 5: P90D — exact days

90 days from Jan 1. Always the same result regardless of year.

Ctrl+Enter to run

Step 6: Month-based duration

Step 6: P3M — calendar months

3 months from Jan 1. Same result here, but P3M can mean different day counts in different years.

Ctrl+Enter to run

Both land on April 1 — but P3M covers 90 days in 2025 (non-leap) and 91 days in 2024 (leap). The month duration preserves the calendar position, not the day count.

Practical rule: Use PnD for exact day counts (regulatory deadlines: "within 60 days"). Use PnM for calendar positioning (payment schedules: "every month on the same date").


Part 3: End-of-Month Preservation

What happens when you add a month to January 31? February has no 31st day.

Step 7: The EOM rule

Step 7: Jan 31 + 1 month

January 31 is the last day of its month. What happens?

Ctrl+Enter to run

Result: 2025-02-28. Because January 31 is the last day of January, the result is the last day of February. This is end-of-month (EOM) preservation.

Step 8: The EOM chain

Step 8: EOM chain

Jan 31 → Feb 28 → Mar 31 → Apr 30. Every step lands on the last day.

Ctrl+Enter to run

The chain never breaks. This is exactly what financial systems need for monthly payment schedules and interest accruals.

Step 9: Non-reversibility warning

Step 9: Non-reversibility

Jan 31 + P1M = Feb 28. But Feb 28 - P1M = Jan 28, NOT Jan 31.

Ctrl+Enter to run

Key insight: Month arithmetic is not always reversible. Use day-count durations (P90D) when round-trip accuracy matters.

Deep dive: The EOM Preservation Rules page has the complete rule set with addition and subtraction tables.


Part 4: Date Navigation

Step 10: day_after and day_before

Step 10: Day navigation

day_after Feb 28 = Mar 1 (non-leap). day_before Mar 1 = Feb 28.

Ctrl+Enter to run

Try changing the year to 2024 (leap year) — day_after Feb 28 will give Feb 29, not Mar 1.

Step 11: Weekday extraction

Step 11: Weekday

ISO 8601: Monday=1, Sunday=7. What day is March 31, 2025?

Ctrl+Enter to run

Step 12: ISO week number

Step 12: ISO week

Jan 1, 2025 — which ISO week? The ISO year may differ from the calendar year.

Ctrl+Enter to run

Part 5: Sequence Generation

sequence(Value, Start, End) generates values in a half-open range [Start, End). When Value is unbound, it produces each value via backtracking.

Step 13: Integer sequence

Step 13: Integer sequence

Generate integers 1 through 5. Half-open: [1, 6) = 1,2,3,4,5.

Ctrl+Enter to run

Step 14: Monthly reporting calendar

Step 14: H1 months

Every month in the first half of 2025.

Ctrl+Enter to run

Step 15: Weekly dates with a step

Step 15: Weekly dates

Every 7 days starting from Jan 1.

Ctrl+Enter to run

Step 16: Decimal sequence — no floating-point drift

Step 16: Decimal sequence

0.0, 0.3, 0.6, 0.9 — exact rational arithmetic, no accumulation error.

Ctrl+Enter to run

Step 17: Empty range = zero results

Step 17: Empty range

Start == End means empty range. Zero results, not an error.

Ctrl+Enter to run

Part 6: Month Boundaries

Financial reporting revolves around month boundaries — period starts, period ends, accrual dates.

Step 18: Last day of a month

Step 18: Month end date

February end: 28 in 2025, 29 in leap year 2024.

Ctrl+Enter to run

Step 19: All month-end dates in a range

Step 19: Month-end dates H1

Every month-end date in the first half of 2025.

Ctrl+Enter to run

Part 7: Range Min and Max

range_min and range_max find the smallest and largest values in a list.

Step 20: Find the min and max

Step 20: range_min / range_max

Find the earliest and latest dates in a set.

Ctrl+Enter to run

Self-Check

  1. What is the difference between P90D and P3M?
  2. What does date_duration("2025-01-31", v.x, "P1M") produce? Why?
  3. Why is Jan 31 + P1M - P1M not always Jan 31?
  4. What does sequence(v.i, 5, 5) produce?
  5. How would you generate all Fridays in January 2025?

What You Learned

ConceptKey Point
date_durationTri-directional: start ↔ end ↔ duration
Day vs month durationsPnD is exact; PnM is calendar-relative
EOM preservationLast-day-of-month stays last-day-of-month
Non-reversibility+P1M then -P1M may not round-trip
sequenceGenerator for integers, decimals, dates, months, years
weekdayISO 8601: Mon=1, Sun=7
month_end_datesGenerator for month-end dates in a range
range_min / range_maxMin/max of any comparable list

Next

Tutorial 3: Intervals & Allen's Temporal Algebra →

Was this helpful?