Laravel uses Carbon (a thin, fluent wrapper around PHP's native DateTime) for every date-related value — created_at, updated_at, and any column cast to datetime come back from Eloquent as ready-to-use Carbon instances, not plain strings.
1. Getting the current date and time
$now = now(); // Carbon instance, current timestamp
$today = today(); // Carbon instance, midnight today
echo $now->format('Y-m-d H:i:s');
echo $now->diffForHumans(); // "3 minutes ago", "in 2 days"
echo $now->dayName; // "Monday"
2. Formatting
$now->format('F j, Y'); // "March 9, 2023"
$now->toDateString(); // "2023-03-09"
$now->toDateTimeString(); // "2023-03-09 14:30:00"
$now->isoFormat('dddd, MMMM D'); // locale-aware formatting, e.g. "Thursday, March 9"
3. Comparing and calculating
$now->isPast();
$now->isFuture();
$now->addDays(7);
$now->subMonths(1);
$now->diffInDays($otherDate);
4. The part that actually causes bugs: timezones
Laravel's own default (config/app.php's timezone key, usually UTC) controls what timezone dates are stored and processed in internally — this should almost always stay UTC, regardless of where users actually are, and conversion to a local timezone should happen at display time, not storage time.
// Storing: always UTC, regardless of the visitor's timezone
$order->created_at = now(); // stored in UTC
// Displaying: convert to the user's timezone only when rendering
$order->created_at->setTimezone($user->timezone)->format('M j, g:i A');
Storing timestamps already converted to a specific user's local timezone is the mistake that causes real problems later — a database full of timestamps in mixed or user-specific timezones can't be reliably sorted, compared, or aggregated across users. Store everything in UTC; convert only for display.
5. Getting a user's timezone dynamically
// A simple approach: store the user's chosen timezone on their profile
$user->timezone = 'America/New_York';
// Then anywhere a date needs to be shown to that user:
$post->published_at->setTimezone($user->timezone ?? 'UTC')->format('M j, Y g:i A');
PHP's DateTimeZone (which Carbon uses internally) supports the full IANA timezone database (America/New_York, Europe/London, etc.) — a raw UTC offset like -05:00 is a weaker choice for a stored user preference, since it doesn't automatically account for daylight saving time the way a named IANA zone does.
6. Querying by date range
Order::whereBetween('created_at', [
now()->subDays(7)->startOfDay(),
now()->endOfDay(),
])->get();
Order::whereDate('created_at', today())->get(); // just today, ignoring time
whereDate() compares only the date portion, ignoring the time — useful for "orders placed today" style queries without needing to manually construct a start/end-of-day range every time.