In Laravel, what do now() and today() return, and how do you show an order's age as '3 days ago' with Carbon?
answer
- Illuminate\Support\Carbon via the Date facade
- today() is midnight
- diffForHumans() adds 'ago'
- Carbon 3: diffInDays is a signed float
- optional time zone argument
basics
~10 snow() returns a Carbon instance for the current moment and today() one for midnight today, both created through the Date facade. $order->created_at->diffForHumans() renders a past date relative to now, such as '3 days ago'.
solid answer
~30 s`now($tz = null)` and `today($tz = null)` are helpers for `Date::now()` and `Date::today()`, so by default they return `Illuminate\Support\Carbon`, Laravel's subclass of `Carbon\Carbon`, in the app's time zone; `today()` is the current date at `00:00:00`. For relative labels, Eloquent timestamps are already Carbon instances, so `$order->created_at->diffForHumans()` gives `3 days ago` for a past date and `3 days from now` for a future one. For numbers, remember that Laravel 13 ships Carbon 3, where `diffInDays()` and friends return a **float** and are **signed**: `Carbon::parse('2026-09-29')->diffInDays('2026-09-26')` is `-3.0`. Pass `absolute: true` or cast when you need a positive whole number.
code
php · 11 lines<?php
use App\Models\Order;
$order = Order::findOrFail($id);
$placedLabel = $order->created_at->diffForHumans(); // "3 days ago"
$ageInDays = (int) $order->created_at->diffInDays(now(), absolute: true); // 3
$isToday = $order->created_at->greaterThanOrEqualTo(today());go deeper
Recall that now() is the current moment, today() is midnight, both return Carbon, and diffForHumans() makes labels like '3 days ago'.
Explain the Date facade behind the helpers, how diffForHumans() words past and future dates, and Carbon 3's signed float diffInDays().
Catch Carbon 2 assumptions after upgrades — unsigned integer diffs — and mutation of model timestamps in date arithmetic.
Set conventions for date handling across the codebase: helpers over native classes, explicit absolute diffs, and immutability where values are shared.
## now() and today() Both are global helpers defined in the framework's foundation helpers: - `now($tz = null)` returns `Date::now($tz)` — the **current moment**; - `today($tz = null)` returns `Date::today($tz)` — the **current date at midnight**. `Date` is Laravel's date facade over `Illuminate\Support\DateFactory`. Unless you configure otherwise, it creates **`Illuminate\Support\Carbon`**, a thin subclass of `Carbon\Carbon` that adds a few Laravel traits. Both helpers accept an optional time-zone argument; without it they use the application time zone from `config/app.php`. | Call | Example value on 2026-09-29 at 14:05 | |---|---| | `now()` | `2026-09-29 14:05:12` | | `today()` | `2026-09-29 00:00:00` | | `now()->startOfDay()` | `2026-09-29 00:00:00` (same as `today()`) | | `today()->subDays(3)` | `2026-09-26 00:00:00` | Prefer the helpers over `new DateTime()` in application code: they go through the date factory (so a global switch to immutable dates applies), and tests can freeze time for everything that uses them. ## Relative labels with diffForHumans() Eloquent timestamp columns such as `created_at` are returned as Carbon instances, so the label is one call: ```php <?php $order->created_at->diffForHumans(); // "3 days ago" $order->ships_at->diffForHumans(); // "2 days from now" $order->created_at->diffForHumans(short: true); // "3d ago" ``` How it decides the wording: 1. with no argument, it compares with **now**, adding `ago` for past dates and `from now` for future ones; 2. with another date, it says `before` or `after` that date instead; 3. `$parts` controls precision — `diffForHumans(parts: 2)` gives `3 days 4 hours ago`; 4. the language follows the configured locale; translating those labels is a localization topic. ## Numeric differences changed in Carbon 3 Laravel 13's framework requires `nesbot/carbon` `^3.8.4`. Carbon 3 changed the `diffIn*` family: | Behaviour | Carbon 2 | Carbon 3 (Laravel 13) | |---|---|---| | Return type | `int` | `float` | | Sign | absolute by default | **signed**: negative when the argument is earlier | | Signature | `diffInDays($date, $absolute = true)` | `diffInDays($date = null, bool $absolute = false, bool $utc = false)` | ```php <?php use Illuminate\Support\Carbon; Carbon::parse('2026-09-29')->diffInDays('2026-09-26'); // -3.0 Carbon::parse('2026-09-29')->diffInDays('2026-09-26', absolute: true); // 3.0 (int) now()->diffInDays($order->created_at, absolute: true); // whole days ``` Code written against Carbon 2 that does `if ($order->created_at->diffInDays() > 30)` still works for past dates, because the argument defaults to now and now is later, so the result is positive; code that calls it the other way round, `now()->diffInDays($order->created_at)`, silently turns negative and the comparison never fires. ## Formatting for display Carbon formats with PHP date format characters or with localized helpers: - `$order->created_at->format('Y-m-d H:i')` — fixed technical format; - `$order->created_at->toDateString()` — `2026-09-26`; - `$order->created_at->isoFormat('LL')` — a locale-aware long date; - `$order->created_at->toIso8601String()` — for APIs and `<time datetime>` attributes. A good order page shows the relative label and keeps the absolute timestamp available, for example in a `title` attribute, so support staff can see the exact moment when a customer says "I ordered yesterday". ## Helpers versus facade versus class | Form | Example | When it fits | |---|---|---| | helper | `now()`, `today()` | everyday application code | | facade | `Date::now()`, `Date::parse($s)` | when you want the configured date class explicitly | | class | `Carbon::parse($s)`, `Carbon::create(2026, 9, 29)` | constructing specific dates, or code that type-hints Carbon | All three end up with Carbon instances; the helper and facade forms respect a global `Date::use()` configuration, while calling a concrete class creates that class regardless. ## Pitfalls interviewers look for - **Mutation:** `Illuminate\Support\Carbon` is mutable, so after `$start = $order->created_at; $end = $start->addDays(14);` the variable `$start` has moved as well. Copy first, or configure immutable dates globally. - **Midnight versus now:** comparing a timestamp with `today()` rather than `now()` shifts results by up to a day. - **Time zones:** `now('Europe/Berlin')` changes the zone of the returned instance, not the application's; storage and zone strategy belong to PHP's date handling in general.
- Why can now()->diffInDays($order->created_at) be negative in Laravel 13?Laravel 13 uses Carbon 3, where `diffInDays()` is signed and returns a float. The method measures from the receiver to the argument, so when the argument is earlier — an order created in the past — the result is negative, for example `-3.25`. Pass `absolute: true` or reverse the operands, then cast if you need an integer.
- In Laravel, what is the difference between comparing an order's timestamp with now() and with today()?`now()` is the current moment; `today()` is midnight at the start of the current day. `created_at >= today()` asks whether the order was placed today at all, while `created_at >= now()->subDay()` asks whether it was placed within the last 24 hours — different answers late in the evening.
diffForHumans() is the shop assistant who says 'that was three days ago', while diffInDays() is the ledger that writes -3.0 and expects you to know which column you subtracted from which.
saying these in an interview costs you the question
- Thinks now() returns a string or a native DateTime.
- Believes today() returns the current time of day.
- Assumes diffInDays() always returns a positive integer in Laravel 13.
- Formats relative ages by hand from timestamps instead of diffForHumans().
- Reuses one Carbon variable as the base for several addDays() calls.