feat(quando-wny): implement explicit parsing with layout format

Add ParseWithLayout() function to handle ambiguous and custom date formats
by providing an explicit Go layout string.

Implementation:
- ParseWithLayout(s, layout string) delegates to time.Parse()
- Wraps result in quando.Date with default EN language
- Returns ErrInvalidFormat on parse failure
- Trims whitespace and validates empty input
- Never panics, always returns errors as values

Features:
- Disambiguate US vs EU slash formats (01/02/2026)
- Support custom formats with month names (9. February 2026)
- Full Go layout format support (reference date: Mon Jan 2 15:04:05 MST 2006)
- Thread-safe and immutable

Testing:
- 13 success test cases (US/EU, custom formats, edge cases)
- 8 error test cases (invalid inputs, validation)
- Immutability test
- 2 benchmarks: ~87-104 ns/op (100x faster than 10µs target)
- Zero allocations
- 100% test coverage for new code
- 3 example tests demonstrating key use cases

Files modified:
- parse.go: Added ParseWithLayout() with comprehensive godoc
- parse_test.go: Added 21 test cases + 2 benchmarks
- example_test.go: Added 3 example functions
This commit is contained in:
Oliver Jakoubek 2026-02-11 19:51:09 +01:00
commit 00353c2d4b
4 changed files with 346 additions and 1 deletions

View file

@ -537,3 +537,34 @@ func ExampleDuration_Human_adaptive() {
// 2 days, 5 hours
// 45 seconds
}
// ExampleParseWithLayout demonstrates parsing with explicit layout format
func ExampleParseWithLayout() {
// US format: month/day/year
dateUS, _ := quando.ParseWithLayout("01/02/2026", "01/02/2006")
fmt.Println("US format:", dateUS) // January 2, 2026
// EU format: day/month/year
dateEU, _ := quando.ParseWithLayout("01/02/2026", "02/01/2006")
fmt.Println("EU format:", dateEU) // February 1, 2026
// Output:
// US format: 2026-01-02 00:00:00
// EU format: 2026-02-01 00:00:00
}
// ExampleParseWithLayout_custom demonstrates custom date format with English month names
func ExampleParseWithLayout_custom() {
date, _ := quando.ParseWithLayout("9. February 2026", "2. January 2006")
fmt.Println(date)
// Output: 2026-02-09 00:00:00
}
// ExampleParseWithLayout_error demonstrates error handling
func ExampleParseWithLayout_error() {
_, err := quando.ParseWithLayout("99/99/2026", "02/01/2006")
if errors.Is(err, quando.ErrInvalidFormat) {
fmt.Println("Invalid date format detected")
}
// Output: Invalid date format detected
}