Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Date Value Objects Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Domain-Driven Design (DDD) Alignment: The package excels in Laravel applications with complex domain logic where date/time granularity must be explicitly modeled (e.g., financial systems, healthcare, or event-driven workflows). Its immutable value objects reduce ambiguity in domain models by enforcing type safety (e.g., LocalDate vs. DateWithTimezone), aligning with Laravel’s growing adoption of DDD patterns.
  • Laravel Synergy:
    • Eloquent Integration: Can replace Carbon in accessors/mutators (e.g., getScheduledAtAttribute(): DateWithTimezone) without modifying database schemas.
    • API Resources: Ideal for request/response DTOs (e.g., HourAndMinutes for time slots in a booking API).
    • Validation: Complements Laravel’s Form Requests by enabling domain-specific validation (e.g., rejecting invalid dates like "February 30").
  • Anti-Pattern Mitigation: Addresses Laravel’s common pitfalls:
    • Timezone Ambiguity: DateWithTimezone enforces explicit timezone handling vs. Carbon’s implicit defaults.
    • Overloaded DateTime: Prevents accidental inclusion of irrelevant fields (e.g., microseconds in a LocalDate).

Integration Feasibility

  • Low-Coupling Design: The package’s pure PHP nature allows integration via Composer without Laravel-specific dependencies. Key leverage points:
    • Service Layer: Inject value objects into Laravel services (e.g., EventSchedulerService using DateWithTimezone).
    • Repository Pattern: Return value objects from repositories (e.g., UserRepository::findByBirthdate(LocalDate $date)).
    • API Contracts: Use in OpenAPI/Swagger schemas to document expected date formats.
  • Carbon Interoperability:
    • Bidirectional Conversion: Implement static methods like DateWithTimezone::fromCarbon(Carbon $carbon) and Carbon::fromDateWithTimezone(DateWithTimezone $dwo).
    • Hybrid Usage: Use Carbon for storage/serialization and value objects for domain logic (e.g., User::birthdate stored as DATE but returned as LocalDate).
  • Validation Integration:
    • Extend Laravel’s Validator with custom rules (e.g., LocalDateRule to validate ISO-8601 dates).
    • Use in Form Requests to enforce domain constraints (e.g., EventRequest requiring HourAndMinutes for time slots).

Technical Risk

  • Maturity and Adoption:
    • Risk: No stars/dependents suggest unproven stability. The Apie monorepo model may lead to undocumented breaking changes.
    • Mitigation:
      • Fork and Patch: Maintain a fork if the package lacks critical features (e.g., Laravel-specific utilities).
      • Feature Flags: Wrap usage in feature flags to isolate changes (e.g., config('app.use_date_value_objects')).
  • Performance Overhead:
    • Risk: Immutable objects may introduce memory/GC overhead vs. Carbon’s mutable design.
    • Mitigation:
      • Benchmark in high-throughput scenarios (e.g., API rate limits, batch jobs).
      • Use value objects sparingly for critical paths (e.g., prefer UnixTimestamp for logs over DateWithTimezone).
  • Laravel-Specific Gaps:
    • Risk: Missing utilities for Eloquent, Queues, or Events.
    • Mitigation:
      • Build custom Laravel wrappers (e.g., DateWithTimezone::fromTimestamp($timestamp) for Eloquent).
      • Pair with Spatie’s Laravel Date for database integration.
  • Testing Complexity:
    • Risk: Undocumented edge cases (e.g., WorksWithMonths across year boundaries).
    • Mitigation:
      • Write comprehensive unit tests for domain-specific logic (e.g., LocalDate::nextMonth()).
      • Use property-based testing (e.g., with PestPHP) to validate edge cases.

Key Questions

  1. Domain Criticality:
    • Are there business-critical use cases where date/time precision directly impacts revenue, compliance, or user experience (e.g., financial settlements, medical appointments)?
  2. Team Readiness:
    • Does the team have experience with DDD and value objects? If not, will this introduce a steep learning curve?
  3. Laravel Ecosystem Dependencies:
    • Are there third-party Laravel packages (e.g., Scout, Cashier) that rely on Carbon/DateTime? How will interoperability be handled?
  4. Long-Term Maintenance:
    • Is the Apie monorepo actively maintained? What’s the deprecation policy for breaking changes?
  5. Alternatives Assessment:
    • Have other packages (e.g., spatie/laravel-date, ramsey/uuid) been evaluated for Laravel-specific needs?
  6. Migration Strategy:
    • What’s the minimum viable integration (e.g., start with LocalDate for user dates) vs. full replacement of Carbon?

Integration Approach

Stack Fit

  • PHP/Laravel Compatibility:
    • PHP 8.1+: Required for named arguments and union types used in the package. Laravel 9+ (PHP 8.1+) is ideal; Laravel 8.x may need Carbon v1.x compatibility checks.
    • Laravel Ecosystem:
      • Eloquent: Use value objects in accessors/mutators (e.g., getEventDate(): DateWithTimezone).
      • API Resources: Leverage for request/response transformation (e.g., JsonResource returning HourAndMinutes).
      • Validation: Integrate with Form Requests and custom validators.
    • Tooling:
      • Composer: Install via composer require apie/date-value-objects.
      • IDE Support: Ensure PHPStorm/VSCode recognize the value objects via Composer autoload.
  • Architectural Patterns:
    • Hexagonal Architecture: Place value objects in the domain layer, with adapters for Laravel’s infrastructure (e.g., CarbonAdapter).
    • CQRS: Use for read models (e.g., LocalDate in projections) and command validation (e.g., DateWithTimezone for event scheduling).
    • Event Sourcing: Immutable objects align with event timestamps and snapshotting.

Migration Path

Phase 1: Pilot Integration (Low Risk)

  • Goal: Validate the package in a non-critical feature.
  • Steps:
    1. Replace Carbon in a New Feature:
      • Example: Use DateWithTimezone for a scheduling module instead of Carbon.
      • Implement a service class (e.g., AppointmentScheduler) that accepts HourAndMinutes.
    2. Add Eloquent Accessors:
      // User.php
      public function birthdate(): LocalDate {
          return LocalDate::fromDateTime($this->attributes['birthdate']);
      }
      
    3. Integrate with Form Requests:
      // CreateAppointmentRequest.php
      public function rules(): array {
          return [
              'time_slot' => ['required', 'date_format:H:i', new ValidHourAndMinutes],
          ];
      }
      
    4. Test Thoroughly:
      • Validate edge cases (e.g., LocalDate::nextMonth() across year boundaries).
      • Ensure serialization/deserialization works (e.g., JSON API responses).

Phase 2: Validation Layer (Medium Risk)

  • Goal: Enforce domain rules via value objects.
  • Steps:
    1. Custom Validators:
      // app/Rules/LocalDateRule.php
      public function passes($attribute, $value) {
          return LocalDate::tryFromString($value) !== null;
      }
      
    2. API Resource Transformation:
      // AppointmentResource.php
      public function toArray($request) {
          return [
              'time_slot' => $this->whenLoaded('time_slot', fn () => $this->time_slot->toString()),
          ];
      }
      
    3. Database Storage:
      • Store raw values (e.g., LocalDate as DATE, UnixTimestamp as BIGINT).
      • Use mutators/accessors to hydrate/dehydrate objects.

Phase 3: Domain Logic Refactor (High Risk)

  • Goal: Replace Carbon/DateTime in core domain logic.
  • Steps:
    1. Service Layer Migration:
      • Replace Carbon with value objects in domain services (e.g., BillingService using LocalDate for month-end calculations).
    2. Repository Pattern:
      • Update repositories to return value objects (e.g., `UserRepository::findByBirthdate(LocalDate $
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours