Skip to content

feat: add DateUnit::Week and DateTimeUnit::Quarter to unit enums #52

Description

@ZialeHub

Summary

The current unit enums cover the most granular time units:

  • DateUnit: Year, Month, Day
  • DateTimeUnit: Year, Month, Day, Hour, Minute, Second

Two highly practical units are missing: Week and Quarter. These appear constantly in scheduling, reporting, and business logic, and consumers currently have to work around their absence by multiplying days or months manually — which is error-prone (e.g. "1 quarter" is not always 3 × 30 days).


Proposed Addition

pub enum DateUnit {
    Year,
    Quarter,  // new
    Month,
    Week,     // new
    Day,
}

pub enum DateTimeUnit {
    Year,
    Quarter,  // new
    Month,
    Week,     // new
    Day,
    Hour,
    Minute,
    Second,
}

Expected Behaviour

Week

A week is exactly 7 days. All existing Span methods must handle it:

// update
date.update(DateUnit::Week, 2)?;     // +14 days
date.update(DateUnit::Week, -1)?;    // -7 days

// next
date.next(DateUnit::Week)?;          // +7 days

// elapsed
let weeks = date_a.unit_elapsed(&date_b, DateUnit::Week)?;  // integer weeks between dates

// clear_unit
date.clear_unit(DateUnit::Week)?;    // rewind to Monday of the current week

Quarter

A quarter is 3 calendar months. It must respect month-end clamping (same as Month already does):

date.update(DateUnit::Quarter, 1)?;  // +3 months (2024-01-31 → 2024-04-30)
date.update(DateUnit::Quarter, -2)?; // -6 months

date.clear_unit(DateUnit::Quarter)?; // first day of the current quarter
// e.g. 2024-11-15 → 2024-10-01  (Q4 starts October)

let quarters = date_a.unit_elapsed(&date_b, DateTimeUnit::Quarter)?;

Implementation Notes

  • Week arithmetic delegates to DateUnit::Day with value * 7 — straightforward.
  • Quarter arithmetic delegates to DateUnit::Month with value * 3.
  • clear_unit(DateUnit::Week) should return the Monday of the week containing self (ISO week definition).
  • clear_unit(DateUnit::Quarter) should return the first day of the quarter: Q1→Jan 1, Q2→Apr 1, Q3→Jul 1, Q4→Oct 1.
  • unit_elapsed for Week = day_elapsed / 7 (integer division, truncated toward zero).
  • unit_elapsed for Quarter = month_elapsed / 3.
  • These additions are non-breaking — existing code using the current enums continues to compile.

Acceptance Criteria

  • DateUnit::Week and DateUnit::Quarter added
  • DateTimeUnit::Week and DateTimeUnit::Quarter added
  • update, next, clear_unit, unit_elapsed, and matches all handle the new variants
  • clear_unit(Week) returns the ISO Monday of the current week
  • clear_unit(Quarter) returns the first day of the current calendar quarter
  • Edge cases tested: week crossing month/year boundary, Q4→Q1 rollover, leap year Q1
  • Doc comments with examples on each new variant

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-domainbusiness logic / coreB-ideaDiscussion; or implementation attempt, to be reviewed before further work

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions