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

Sun Laravel Package

spatie/sun

Compute sun position times for any coordinates: get sunrise, solar noon (zenith), and sunset as Carbon instances, optionally for a specific date. Simple PHP API from Spatie, ideal for scheduling, dashboards, and daylight-aware features.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require spatie/sun
    

    No additional configuration is required—just autoload.

  2. First Use Case: Check Sunrise/Sunset

    use Spatie\Sun\Sun;
    
    $sun = new Sun('2023-12-25', '51.2194', '4.4025'); // Date, latitude, longitude
    $sunrise = $sun->sunrise();
    $sunset = $sun->sunset();
    
    echo "Sunrise: {$sunrise->format('H:i')}, Sunset: {$sunset->format('H:i')}";
    

Implementation Patterns

1. Dynamic Location Handling

  • Use Case: Fetching sun data for multiple locations (e.g., user profiles, weather apps).
  • Pattern:
    $locations = [
        ['lat' => '51.2194', 'lng' => '4.4025'], // Amsterdam
        ['lat' => '34.0522', 'lng' => '-118.2437'], // Los Angeles
    ];
    
    foreach ($locations as $location) {
        $sun = new Sun(now(), $location['lat'], $location['lng']);
        echo "Sunrise in {$location['lat']},{$location['lng']}: {$sun->sunrise()}\n";
    }
    
  • Tip: Cache results for static locations (e.g., store Sun instances in a service container).

2. Timezone-Aware Calculations

  • Use Case: Displaying sun times in user-specific timezones.
  • Pattern:
    $sun = new Sun(now(), '51.2194', '4.4025');
    $sunrise = $sun->sunrise()->setTimezone(new \DateTimeZone('Europe/Amsterdam'));
    
  • Integration Tip: Use Laravel’s Carbon for timezone handling:
    use Carbon\Carbon;
    $sunrise = Carbon::parse($sun->sunrise())->timezone('Europe/Amsterdam');
    

3. Event-Based Triggers

  • Use Case: Sending notifications when the sun rises/sets (e.g., for solar-powered systems).
  • Pattern:
    $sun = new Sun(now(), '51.2194', '4.4025');
    if ($sun->isDaytime()) {
        event(new SunriseEvent());
    }
    
  • Laravel Integration: Create a custom event listener or use Laravel’s scheduler:
    // app/Console/Kernel.php
    protected function schedule(Schedule $schedule) {
        $schedule->call(function () {
            $sun = new Sun(now(), '51.2194', '4.4025');
            if ($sun->isDaytime()) {
                // Trigger logic
            }
        })->everyMinute();
    }
    

4. API Wrapping

  • Use Case: Exposing sun data via a Laravel API.
  • Pattern:
    Route::get('/sun/{latitude}/{longitude}', function ($latitude, $longitude) {
        $sun = new Sun(now(), $latitude, $longitude);
        return response()->json([
            'sunrise' => $sun->sunrise()->format('H:i'),
            'sunset' => $sun->sunset()->format('H:i'),
            'is_daytime' => $sun->isDaytime(),
        ]);
    });
    

Gotchas and Tips

Pitfalls

  1. Date Handling:

    • The package uses Carbon internally, but ensure your input dates are valid. Invalid dates (e.g., 2023-02-30) will throw exceptions.
    • Fix: Validate dates before passing them to Sun:
      use Carbon\Carbon;
      $date = Carbon::parse($userInputDate);
      if ($date->isValid()) {
          $sun = new Sun($date, $lat, $lng);
      }
      
  2. Longitude/Latitude Range:

    • The algorithm assumes valid coordinates (-90 ≤ latitude ≤ 90, -180 ≤ longitude ≤ 180). Out-of-range values may return incorrect results.
    • Fix: Sanitize inputs:
      $latitude = max(-90, min(90, $latitude));
      $longitude = max(-180, min(180, $longitude));
      
  3. Timezone Confusion:

    • Sunrise/sunset times are calculated in UTC by default. If your app uses a different timezone, explicitly convert results (see Implementation Patterns).
    • Tip: Document this behavior in your API responses.
  4. Daylight Saving Time (DST):

    • The package does not account for DST in location timezones. Results are based on the geographical position, not the local clock.
    • Workaround: Manually adjust for DST if needed (e.g., using Carbon timezone rules).

Debugging Tips

  1. Verify Calculations:

    • Cross-check results with timeanddate.com’s sun calculator for edge cases (e.g., polar regions).
    • Example for polar day/night:
      $sun = new Sun('2023-06-21', '80', '10'); // Near the Arctic Circle
      echo $sun->isDaytime() ? 'Polar Day' : 'Polar Night';
      
  2. Logging:

    • Log raw inputs/outputs for debugging:
      \Log::debug('Sun calculation', [
          'date' => $sun->date(),
          'latitude' => $latitude,
          'longitude' => $longitude,
          'sunrise' => $sun->sunrise(),
          'sunset' => $sun->sunset(),
      ]);
      

Extension Points

  1. Custom Sunrise/Sunset Definitions:

    • The package uses a fixed astronomical algorithm. Override the calculation by extending the class:
      class CustomSun extends \Spatie\Sun\Sun {
          public function sunrise() {
              // Custom logic (e.g., nautical sunrise)
              return Carbon::now()->addHours(6); // Placeholder
          }
      }
      
  2. Additional Data:

    • Extend the package to include solar noon, twilight times, or elevation angles:
      // Add to Sun.php (or a trait)
      public function solarNoon() {
          $sunrise = $this->sunrise();
          $sunset = $this->sunset();
          return $sunrise->copy()->addHours(($sunset->getTimestamp() - $sunrise->getTimestamp()) / 2);
      }
      
  3. Batch Processing:

    • Process multiple dates/locations efficiently:
      $results = collect($dates)->map(function ($date) use ($lat, $lng) {
          return [
              'date' => $date,
              'sunrise' => (new Sun($date, $lat, $lng))->sunrise(),
          ];
      });
      

Config Quirks

  • No Configuration File: The package is zero-config. All logic is runtime-based.
  • Performance: For high-frequency calls (e.g., every minute), cache results aggressively:
    $cacheKey = "sun:{$lat}:{$lng}:{$date->format('Y-m-d')}";
    $sunData = Cache::remember($cacheKey, now()->addHours(1), function () use ($date, $lat, $lng) {
        return (new Sun($date, $lat, $lng))->getSunriseAndSunset();
    });
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport