today

Returns a Carbon instance for the current date with the time set to 00:00:00.

Signature
today($tz = null): CarbonInterface

Parameters

ParameterTypeDescription
$$tzoptionalDateTimeZone|string|int|BackedEnum|null= nullTimezone used to decide which calendar date it currently is, and carried by the returned instance. Defaults to the application timezone.

Return value

CarbonInterfaceAn Illuminate\Support\Carbon instance for the current date with the time zeroed to 00:00:00.000000.

Errors

Throws Carbon\Exceptions\InvalidTimeZoneException when the timezone string is not a recognised identifier.

Changelog

  • PHP 12.xDeclared as returning CarbonInterface and delegates to Date::today(), so a custom date class registered with Date::use() is honoured.

today() is now() with the time cleared: same calendar date, time 00:00:00.000000. It is the value you want whenever a comparison should be about the day rather than the moment — filtering rows created today, checking whether a due date has passed, or building the lower bound of a date range.

Why not just use now()

A where('due_at', '<=', now()) filter silently excludes anything due later today, because now() carries the current time of day. With today() the boundary sits at midnight and the result stops depending on when the query runs — which also makes it deterministic in tests.

The timezone decides the date

The argument does more than tag the instance: it decides which calendar date it is. At 23:30 UTC, today() and today('Australia/Sydney') are a day apart. If users pick dates in their own timezone, pass that timezone in rather than converting afterwards.

Ranges

For a whole day, pair it with the start of tomorrow — whereBetween('created_at', [today(), today()->addDay()]) is inclusive at both ends, so prefer a half-open range or today()->endOfDay(), remembering that end-of-day carries 999999 microseconds.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Filtering records created since midnight without a hard-coded date string.
  • Comparing a due date against the current day, ignoring the time of day.
  • Building the lower bound of a report range that runs on a schedule.

Frequently asked questions

What is the difference between today() and now()?

today() returns the current date with the time set to 00:00:00, while now() keeps the current time of day. Use today() when a comparison is about the calendar day, and now() when the exact moment matters.

How do I get tomorrow or yesterday?

Call today()->addDay() and today()->subDay(), which stay at midnight. Carbon also exposes Carbon::tomorrow() and Carbon::yesterday(), which accept the same optional timezone argument.

Does today() use the user's timezone?

No — it uses your application's configured timezone unless you pass one, so pass the user's identifier such as today('Australia/Sydney') when the calendar date should be theirs. The timezone determines which date it is, not just how the value is displayed.

More examples

Scoping a query to the current day

The half-open range [today, tomorrow) catches every row from the day without the double-counting an inclusive whereBetween would risk at the boundary. Using today() instead of now() keeps the query's meaning the same whether it runs at 09:00 or 23:00.

Example · php
<?php

use App\Models\Order;

// Everything placed since midnight, exclusive of tomorrow.
$todaysOrders = Order::query()
    ->where('created_at', '>=', today())
    ->where('created_at', '<', today()->addDay())
    ->orderBy('created_at')
    ->get();

// Anything still open whose due date is in the past.
$overdue = Order::query()
    ->whereNull('completed_at')
    ->whereDate('due_on', '<', today())
    ->count();

echo $todaysOrders->count(), ' orders today, ', $overdue, ' overdue', PHP_EOL;

Day arithmetic reads cleanly from midnight

Starting from midnight makes diffInDays return a whole number instead of a fraction, because there is no leftover time-of-day to account for. The same calculation from now() would give 30 minus a fraction of a day.

Example · php
<?php

use Carbon\Carbon;

Carbon::setTestNow('2026-03-14 09:41:07');

$yesterday = today()->subDay();
$weekStart = today()->startOfWeek();
$in30Days  = today()->addDays(30);

echo $yesterday->toDateString(), "\n";  // 2026-03-13
echo $weekStart->toDateString(), "\n";  // 2026-03-09
echo $in30Days->toDateString(), "\n";   // 2026-04-13
var_dump(today()->diffInDays($in30Days)); // float(30)

Carbon::setTestNow();

A user's day, not the server's

today($zone) picks the calendar date as the user experiences it, then ->utc() converts both boundaries back for a UTC-stored column. Without the timezone argument, users east or west of the server see the wrong day near midnight.

Example · php
<?php

use App\Models\Entry;
use Illuminate\Http\Request;

public function index(Request $request)
{
    $zone = $request->user()->timezone ?? config('app.timezone');

    $start = today($zone);
    $end = $start->copy()->addDay();

    return Entry::query()
        ->whereBetween('logged_at', [$start->utc(), $end->utc()])
        ->get();
}

Discussion

  • Be the first to comment on this lesson.