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 Time Precision Laravel Package

digital-craftsman/date-time-precision

Thin PHP value objects for precise date/time concepts: Moment (UTC-backed) plus Time, Date, Month, Year, Day, Weekday and collections. Avoid misleading DateTime comparisons, handle timezone-safe modifications (DST), with Symfony normalizers and Doctrine types.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Precision-Oriented Design: The package excels in addressing a critical pain point in Laravel/PHP applications—namely, the ambiguity and inefficiency of using DateTime for non-moment-specific operations (e.g., comparing times, dates, or months). Its value-object approach (Moment, Time, Date, Month, Year) aligns well with Domain-Driven Design (DDD) and Laravel’s Eloquent/Doctrine integration, reducing boilerplate and improving type safety.
  • UTC-First Philosophy: The package enforces UTC as the canonical timezone for Moment objects while allowing timezone-aware modifications for business logic (e.g., modifyInTimeZone). This is highly compatible with Laravel’s default timezone handling (e.g., config('app.timezone')) but requires explicit opt-in for timezone-aware operations.
  • Immutability: The immutable design of Moment and its components prevents side effects, which is a best practice for Laravel services and repositories. This contrasts with PHP’s mutable DateTime, reducing bugs in stateful operations.

Integration Feasibility

  • Symfony Bundle Compatibility: While this is a Symfony bundle, it can be used in Laravel via Composer (Symfony’s HttpKernel and DependencyInjection are not required). The package’s Doctrine DBAL types and Symfony normalizers are optional but valuable for:
    • Database storage: Doctrine types for Moment, Date, etc., enable direct ORM mapping (e.g., in Laravel’s Eloquent models via hasOne/belongsTo with custom accessors).
    • API serialization: Normalizers integrate with Symfony’s Serializer, but Laravel’s Fractal/JSONAPI can adapt via custom transformers.
  • Laravel-Specific Considerations:
    • Carbon Integration: The package does not replace Carbon, but Moment can wrap Carbon instances for consistency. A bridge adapter (e.g., CarbonMoment) would be needed for seamless interoperability.
    • Artisan/Console: The Clock interface (with SystemClock/FrozenClock) enables time-freezing for tests, which is already a Laravel pattern (e.g., Carbon::setTestNow()). This can be extended to support the package’s Clock.
    • Query Builder: The package lacks direct integration with Laravel’s Query Builder, but custom accessors/mutators can translate Moment operations into SQL (e.g., whereDate('created_at', '>', $date)).

Technical Risk

  • Pre-1.0 Stability: The package is not yet at v1.0, with breaking changes between minor versions (e.g., PHP 8.1→8.2 drop, Symfony 6.3→7.0). Mitigation:
    • Pin to 0.14.* in composer.json to avoid surprises.
    • Feature flags for new methods (e.g., Day/Days in v0.14.0) to isolate changes.
  • Doctrine Dependency: Laravel’s Eloquent does not use Doctrine ORM, but the package’s DBAL types can be adapted for Eloquent via:
    • Custom Eloquent attributes (Laravel 8.73+).
    • Accessors/mutators to serialize/deserialize Moment objects.
  • Performance Overhead: The package wraps DateTime, adding a thin abstraction layer. Benchmarking is needed for high-frequency operations (e.g., bulk inserts), but the overhead is likely negligible for most use cases.
  • Testing Complexity: The package’s mutation testing (80% coverage) is a strength, but Laravel’s mocking ecosystem (e.g., Mockery) may need adjustments for Clock/Moment interactions.

Key Questions

  1. Adoption Scope:
    • Should Moment replace all DateTime/Carbon instances, or only for domain-specific logic (e.g., booking systems)?
    • How will this interact with Laravel’s built-in date helpers (e.g., now(), Carbon::parse())?
  2. Migration Strategy:
    • What’s the fallback plan if the package introduces breaking changes mid-project?
    • How will legacy DateTime code coexist with Moment (e.g., via adapters)?
  3. Testing:
    • How will time-sensitive tests (e.g., feature tests with travel()) adapt to the Clock interface?
    • Should FrozenClock replace Laravel’s Carbon::setTestNow()?
  4. Database Schema:
    • Will existing timestamp/date columns need migration to use the package’s Doctrine types?
    • How will raw SQL queries (e.g., DB::raw) interact with Moment objects?
  5. Performance:
    • Are there hot paths (e.g., API rate-limiting) where Moment overhead could impact latency?
    • How does the package handle timezone conversions under load?

Integration Approach

Stack Fit

  • Laravel Core:
    • Replaces: DateTime/Carbon for domain-specific date logic (e.g., business hours, scheduling).
    • Complements: Carbon for low-level operations (e.g., parsing ISO strings, timezone conversions).
    • Extends: Eloquent models via custom accessors or Eloquent attributes (Laravel 8.73+).
  • Symfony Dependencies:
    • Optional: Doctrine DBAL types (for non-Eloquent projects) and Symfony normalizers (for API platforms using Symfony’s Serializer).
    • Alternative: Use digital-craftsman/self-aware-normalizers directly in Laravel via spatie/fractal or laravel/serializable.
  • Testing:
    • Clock Interface: Replace Carbon::setTestNow() with FrozenClock for consistent time freezing.
    • Mocking: Use Mockery to stub Moment methods in unit tests.

Migration Path

  1. Phase 1: Pilot Project
    • Scope: Start with a single module (e.g., bookings, events) where date precision is critical.
    • Implementation:
      • Replace Carbon with Moment in domain services.
      • Use adapters (e.g., CarbonMoment) to bridge existing DateTime code.
      • Add custom Eloquent accessors for Moment serialization.
    • Tools:
      • Rector for automated DateTimeMoment refactoring.
      • PHPStan to enforce Moment usage in new code.
  2. Phase 2: Core Integration
    • Eloquent Models: Replace timestamp fields with Moment types via database migrations (if using Doctrine types).
    • API Layer: Integrate normalizers with Fractal/JSONAPI for consistent serialization.
    • Console/Jobs: Replace Carbon::now() with SystemClock::now().
  3. Phase 3: Full Replacement
    • Global Replacement: Use Moment as the default date type in the application.
    • Carbon Fallback: Keep Carbon for legacy code or performance-critical paths.

Compatibility

Laravel Component Compatibility Workaround
Eloquent Low (Doctrine types not natively supported) Custom accessors or Eloquent attributes.
Query Builder Medium (requires SQL translation) Use Moment::toDateTime() for raw queries.
Carbon High (via adapters) CarbonMoment wrapper class.
API Serialization Medium (Symfony normalizers not native) Use spatie/fractal or custom JSON serialization.
Testing (Pest/PhpUnit) High (Clock interface supports time freezing) Replace Carbon::setTestNow() with FrozenClock.
Cache (Redis/Memcached) High (serialization works with normalizers) Ensure Moment objects are serializable.
Queues/Jobs High (immutability prevents side effects) Use Moment in job payloads.

Sequencing

  1. Dependency Setup:
    • Install the package with composer require digital-craftsman/date-time-precision:0.14.*.
    • Add Clock binding to Laravel’s service container:
      $app->bind(Clock::class, function () {
          return app()->environment('testing')
              ? new FrozenClock()
              : new SystemClock();
      });
      
  2. Domain Layer:
    • Replace DateTime/Carbon with Moment in services/repositories.
    • Example:
      // Before
      $now = Carbon
      
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.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle