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 Interval Laravel Package

herrera-io/date-interval

Extends PHP’s DateInterval with handy conversions: turn intervals into ISO interval specs and seconds, and recreate intervals from seconds. Useful for normalizing and serializing durations (e.g., P2H <-> 7200).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require herrera-io/date-interval:^1.0
    

    Ensure ext-bcmath is enabled in your PHP environment (required for toSeconds()).

  2. First Use Case: Convert a DateInterval to a string spec or seconds for API responses, database storage, or calculations:

    use Herrera\DateInterval\DateInterval;
    
    // Create from ISO 8601 spec
    $interval = new DateInterval('P1Y2M3DT4H5M6S');
    echo $interval->toSpec(); // "P1Y2M3DT4H5M6S"
    
    // Convert to seconds for arithmetic
    $seconds = $interval->toSeconds();
    echo $seconds; // 32578066 (total seconds)
    
    // Static alternative
    echo DateInterval::toSeconds(new \DateInterval('P1D')); // 86400
    
  3. Where to Look First:

    • Core Methods: Prioritize toSpec() and toSeconds().
    • Laravel Integration: Check the wiki’s API section for Laravel-specific quirks (e.g., Carbon compatibility).
    • Edge Cases: Review the tests for handling negative intervals, fractional seconds, and timezone pitfalls.

Implementation Patterns

Usage Patterns

  1. API Responses: Serialize DateInterval objects to ISO 8601 specs for consistency:

    return response()->json([
        'duration' => (new DateInterval('P1M'))->toSpec(),
    ]);
    
  2. Database Storage: Store intervals as seconds in a bigint column (e.g., for PostgreSQL INTERVAL compatibility):

    $interval = new DateInterval('P2W');
    $model->duration_seconds = $interval->toSeconds();
    $model->save();
    
  3. Scheduling: Parse cron-like intervals into seconds for Laravel’s schedule:

    $interval = new DateInterval('P1DT2H');
    $seconds = $interval->toSeconds();
    // Use $seconds in custom scheduling logic
    
  4. Carbon Bridge: Extend Carbon’s Interval class to use this package’s methods:

    use Herrera\DateInterval\DateInterval;
    
    class CarbonInterval extends \Carbon\CarbonInterval {
        public function toSpec(): string {
            return (new DateInterval($this->interval))->toSpec();
        }
    }
    

Workflows

  1. Input Validation: Validate ISO 8601 specs before creating DateInterval objects:

    use Herrera\DateInterval\DateInterval;
    
    $spec = request('interval');
    try {
        $interval = new DateInterval($spec);
    } catch (\InvalidArgumentException $e) {
        return response()->json(['error' => 'Invalid interval'], 400);
    }
    
  2. Time-Based Policies: Use toSeconds() for rate limiting or throttling:

    $window = new DateInterval('PT1H');
    $windowSeconds = $window->toSeconds();
    // Compare against current timestamp in seconds
    
  3. Legacy System Interop: Convert between this package and native DateInterval:

    $nativeInterval = new \DateInterval('P1D');
    $extendedInterval = new DateInterval($nativeInterval->format('%aD%hH%iM%sS'));
    

Integration Tips

  1. Service Provider Binding: Bind the package to Laravel’s container for dependency injection:

    $this->app->bind(\DateInterval::class, function ($app) {
        return new \Herrera\DateInterval\DateInterval(...);
    });
    
  2. Facade for Convenience: Create a facade to simplify usage:

    // app/Facades/Interval.php
    namespace App\Facades;
    
    use Illuminate\Support\Facades\Facade;
    use Herrera\DateInterval\DateInterval;
    
    class Interval extends Facade {
        protected static function getFacadeAccessor() {
            return DateInterval::class;
        }
    }
    

    Register in AppServiceProvider:

    Facade::clearResolvedInstanceFor('interval');
    
  3. Testing: Mock the package in unit tests:

    $this->partialMock(DateInterval::class, ['toSeconds'])
         ->shouldReceive('toSeconds')
         ->andReturn(3600);
    

Gotchas and Tips

Pitfalls

  1. bcmath Dependency:

    • Issue: toSeconds() requires the bcmath extension, which may not be enabled by default.
    • Fix: Add to php.ini or Dockerfile:
      extension=bcmath
      
    • Fallback: Use gmp or math extensions if bcmath is unavailable (check the wiki).
  2. Timezone Sensitivity:

    • Issue: DateInterval calculations are timezone-agnostic, but toSeconds() may behave unexpectedly with DST transitions.
    • Fix: Ensure consistent timezone handling:
      $interval = new DateInterval('P1D');
      $interval->setTimezone(new \DateTimeZone('UTC'));
      
  3. Fractional Seconds:

    • Issue: toSeconds() truncates fractional seconds (e.g., PT0.5S becomes 0).
    • Fix: Use DateTime for sub-second precision or round manually:
      $seconds = round($interval->toSeconds(), 2);
      
  4. Negative Intervals:

    • Issue: Negative intervals (e.g., -P1D) may not work as expected with toSeconds().
    • Fix: Validate input or handle manually:
      if ($interval->invert === 1) {
          $seconds = -$interval->toSeconds();
      }
      
  5. Archived Package Risks:

    • Issue: No updates since 2016; potential bugs in edge cases.
    • Fix: Fork the repo or use a modern alternative like carbon/carbon for new projects.

Debugging

  1. Invalid Specs:

    • Error: InvalidArgumentException when creating DateInterval.
    • Debug: Validate specs with regex or use Carbon’s createFromFormat():
      if (!preg_match('/^P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)(S|s))?)?$/', $spec)) {
          throw new \InvalidArgumentException('Invalid interval spec');
      }
      
  2. Unexpected Seconds:

    • Issue: toSeconds() returns incorrect values.
    • Debug: Compare with manual calculation:
      $expected = (24 * 60 * 60) + (3 * 60 * 60); // 2 days + 3 hours
      $actual = (new DateInterval('P2DT3H'))->toSeconds();
      
  3. Serialization Errors:

    • Issue: DateInterval fails to serialize/deserialize (e.g., in queues).
    • Fix: Convert to spec or seconds before storing:
      $interval = new DateInterval('P1D');
      $data = ['interval_spec' => $interval->toSpec()];
      

Config Quirks

  1. Laravel Cache:

    • Issue: Cached DateInterval objects may lose precision.
    • Fix: Cache as specs or seconds:
      Cache::put('interval', $interval->toSpec(), $interval->toSeconds());
      
  2. Database Storage:

    • Issue: Storing DateInterval objects directly in databases (e.g., JSON) may cause issues.
    • Fix: Store as specs or seconds:
      $model->interval = $interval->toSpec(); // or $interval->toSeconds()
      

Extension Points

  1. Custom Interval Classes: Extend Herrera\DateInterval\DateInterval for domain-specific logic:

    class BillingInterval extends DateInterval {
        public function toBillingCycles(): int {
            return $this->toSeconds() / (60 * 60 * 24); // Simplified
        }
    }
    
  2. Carbon Integration: Add methods to Carbon’s Interval class:

    \Carbon\CarbonInterval::macro('toSpec',
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky