apie/date-value-objects
Date-related value objects for PHP/Apie that model only the date/time parts you need (LocalDate, Time, HourAndMinutes, UnixTimestamp, DateWithTimezone). Helps validate expected formats without relying on full DateTimeImmutable.
LocalDate, HourAndMinutes) to align with business logic, reducing ambiguity in domain models and improving code maintainability. Ideal for projects where date/time logic is core to the domain (e.g., healthcare, finance, or scheduling platforms).Carbon or DateTime are overkill or insufficient. For example:
HourAndMinutes) or patient admission dates (LocalDate).UnixTimestamp) for audit trails or regulatory reporting.DateWithTimezone to enforce timezone-aware bookings, reducing bugs from implicit timezone assumptions.WorksWithMonths/WorksWithYears to model subscription billing cycles (e.g., "charge on the 1st of every month").UnixTimestamp to ensure immutability in event logs.LocalDate for user-facing dates to avoid timezone conversion pitfalls in UI layers.HourAndMinutes for appointment APIs).Adopt If:
DateTimeImmutable or Carbon cannot enforce without additional validation.DateTime/Carbon instances.Carbon for lightweight date logic, especially in performance-sensitive applications.Avoid If:
Carbon or PHP-Intl for advanced features.DateTime or Carbon with optimized formats.Carbon macros, Eloquent casting) and lack the bandwidth to build custom integrations.Look Elsewhere If:
Carbon or Moment.js (for JavaScript interop).Carbon or Spatie’s Date.react-datepicker alongside this package for backend validation."This package lets us model dates as precise, business-aligned objects—like LocalDate for user-facing dates or HourAndMinutes for appointments—reducing bugs from invalid inputs (e.g., 'February 30') while keeping our stack lightweight. It’s a MIT-licensed, Laravel-friendly alternative to bloated libraries like Carbon, cutting development time for time-sensitive features like subscriptions or scheduling. The low-risk adoption starts with pilot features, and the long-term payoff is fewer data integrity issues and cleaner domain models. Think of it as 'type safety for dates'—just like we enforce types for user IDs or currencies."
Key Talking Points:
WorksWithMonths mirror real-world rules (e.g., "charge on the 1st of every month").*"Apie’s date value objects solve the ‘DateTime bloat’ problem: instead of carrying hours/minutes/timezones when you only need a date, we use immutable, type-safe primitives like LocalDate or UnixTimestamp. Here’s how it helps us:
Problems It Solves:
nextMonth() handle edge cases (e.g., Jan 31 → Feb 28) automatically, reducing null checks.EventDate = DateWithTimezone) mirror business logic, making code self-documenting.Carbon::modify() side effects).Tradeoffs:
Carbon/DateTime to value objects (e.g., LocalDate instead of Carbon::now()->format('Y-m-d')).How to Start:
Carbon in new features (e.g., a scheduling module) with DateWithTimezone and HourAndMinutes.LocalDate in Form Requests to validate user inputs (e.g., date fields).SubscriptionService uses WorksWithMonths for billing cycles).Carbon in legacy code only where date logic is complex or bug-prone.Example Migration:
// Before (mutable, ambiguous)
$date = Carbon::parse($request->input('event_date'));
// After (immutable, explicit)
$date = LocalDate::fromString($request->input('event_date'));
$event = new Event($date, $request->input('title'));
Tools to Leverage:
Carbon::instance($dateWithTimezone) for interop with existing code.LocalDate::nextMonth() on Jan 31 → Feb 28).#[Assert\Type(type: LocalDate::class)]) for IDE support.When to Avoid:
Carbon’s flexibility is critical (e.g., complex timezone conversions).Next Steps:
How can I help you explore Laravel packages today?