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.
Installation
composer require spatie/sun
No additional configuration is required—just autoload.
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')}";
sunrise(), sunset(), isDaytime(), isNighttime(), getSunPosition().$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";
}
Sun instances in a service container).$sun = new Sun(now(), '51.2194', '4.4025');
$sunrise = $sun->sunrise()->setTimezone(new \DateTimeZone('Europe/Amsterdam'));
Carbon for timezone handling:
use Carbon\Carbon;
$sunrise = Carbon::parse($sun->sunrise())->timezone('Europe/Amsterdam');
$sun = new Sun(now(), '51.2194', '4.4025');
if ($sun->isDaytime()) {
event(new SunriseEvent());
}
// 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();
}
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(),
]);
});
Date Handling:
Carbon internally, but ensure your input dates are valid. Invalid dates (e.g., 2023-02-30) will throw exceptions.Sun:
use Carbon\Carbon;
$date = Carbon::parse($userInputDate);
if ($date->isValid()) {
$sun = new Sun($date, $lat, $lng);
}
Longitude/Latitude Range:
$latitude = max(-90, min(90, $latitude));
$longitude = max(-180, min(180, $longitude));
Timezone Confusion:
Daylight Saving Time (DST):
Carbon timezone rules).Verify Calculations:
$sun = new Sun('2023-06-21', '80', '10'); // Near the Arctic Circle
echo $sun->isDaytime() ? 'Polar Day' : 'Polar Night';
Logging:
\Log::debug('Sun calculation', [
'date' => $sun->date(),
'latitude' => $latitude,
'longitude' => $longitude,
'sunrise' => $sun->sunrise(),
'sunset' => $sun->sunset(),
]);
Custom Sunrise/Sunset Definitions:
class CustomSun extends \Spatie\Sun\Sun {
public function sunrise() {
// Custom logic (e.g., nautical sunrise)
return Carbon::now()->addHours(6); // Placeholder
}
}
Additional Data:
// 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);
}
Batch Processing:
$results = collect($dates)->map(function ($date) use ($lat, $lng) {
return [
'date' => $date,
'sunrise' => (new Sun($date, $lat, $lng))->sunrise(),
];
});
$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();
});
How can I help you explore Laravel packages today?