feat(quando-b4r): implement Add and Sub arithmetic operations
- Add Add(value, unit) method for all 8 units - Add Sub(value, unit) method (wraps Add with negative value) - Implement month-end overflow logic for Months/Quarters/Years - When adding months, if target day doesn't exist, snap to last day of month - Handle all month-end combinations correctly - Leap year support (Feb 29 edge cases) - DST-safe calendar day arithmetic for Days unit - Negative value support (Add(-1) == Sub(1)) - Method chaining support (fluent API) - Immutability verified (original date never modified) - Timezone preservation across operations - Comprehensive table-driven tests for month-end edge cases - All 30/31 day month combinations tested - Leap year tests (Feb 29 -> Feb 28) - Cross-year boundary tests - Negative value tests - Method chaining tests - Performance benchmarks (all < 1µs) - 98.8% test coverage (exceeds 95% requirement) - Godoc with month-end overflow examples Benchmark results: - AddDays: ~42ns (< 1µs target) ✓ - AddMonths: ~191ns (< 1µs target) ✓ - AddYears: ~202ns (< 1µs target) ✓ - Method chaining: ~263ns for 3 ops ✓ - Zero allocations for all operations All acceptance criteria met: ✓ Add() implemented for all 8 units ✓ Sub() implemented for all 8 units ✓ Month-end overflow logic correct ✓ Leap year handling (Feb 29 edge cases) ✓ DST handling (calendar days) ✓ Negative values supported ✓ Method chaining works ✓ Unit tests with 98.8% coverage ✓ Table-driven tests for month-end edge cases ✓ Benchmarks meet <1µs target ✓ Godoc comments with month-end examples
This commit is contained in:
parent
2bf1df03ea
commit
7c7cb1a4d9
4 changed files with 602 additions and 2 deletions
|
|
@ -312,3 +312,56 @@ func Example_errorTypes() {
|
|||
// invalid timezone
|
||||
// date overflow
|
||||
}
|
||||
|
||||
// ExampleDate_Add demonstrates date arithmetic
|
||||
func ExampleDate_Add() {
|
||||
date := quando.From(time.Date(2026, 1, 15, 12, 0, 0, 0, time.UTC))
|
||||
|
||||
fmt.Println("Original:", date)
|
||||
fmt.Println("+1 day:", date.Add(1, quando.Days))
|
||||
fmt.Println("+1 month:", date.Add(1, quando.Months))
|
||||
fmt.Println("+1 year:", date.Add(1, quando.Years))
|
||||
// Output:
|
||||
// Original: 2026-01-15 12:00:00
|
||||
// +1 day: 2026-01-16 12:00:00
|
||||
// +1 month: 2026-02-15 12:00:00
|
||||
// +1 year: 2027-01-15 12:00:00
|
||||
}
|
||||
|
||||
// ExampleDate_Add_monthEndOverflow demonstrates month-end overflow behavior
|
||||
func ExampleDate_Add_monthEndOverflow() {
|
||||
// When adding months, if target day doesn't exist, snap to month end
|
||||
date := quando.From(time.Date(2026, 1, 31, 12, 0, 0, 0, time.UTC))
|
||||
|
||||
fmt.Println("Jan 31 + 1 month:", date.Add(1, quando.Months))
|
||||
fmt.Println("Jan 31 + 2 months:", date.Add(2, quando.Months))
|
||||
// Output:
|
||||
// Jan 31 + 1 month: 2026-02-28 12:00:00
|
||||
// Jan 31 + 2 months: 2026-03-31 12:00:00
|
||||
}
|
||||
|
||||
// ExampleDate_Sub demonstrates date subtraction
|
||||
func ExampleDate_Sub() {
|
||||
date := quando.From(time.Date(2026, 3, 31, 12, 0, 0, 0, time.UTC))
|
||||
|
||||
fmt.Println("Original:", date)
|
||||
fmt.Println("-1 day:", date.Sub(1, quando.Days))
|
||||
fmt.Println("-1 month:", date.Sub(1, quando.Months))
|
||||
// Output:
|
||||
// Original: 2026-03-31 12:00:00
|
||||
// -1 day: 2026-03-30 12:00:00
|
||||
// -1 month: 2026-02-28 12:00:00
|
||||
}
|
||||
|
||||
// ExampleDate_Add_chaining demonstrates method chaining
|
||||
func ExampleDate_Add_chaining() {
|
||||
date := quando.From(time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC))
|
||||
|
||||
result := date.
|
||||
Add(1, quando.Months).
|
||||
Add(15, quando.Days).
|
||||
Sub(2, quando.Hours)
|
||||
|
||||
fmt.Println(result)
|
||||
// Output: 2026-02-16 10:00:00
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue