PHP Date and Time

sa sahaya jerish Updated 17 Oct 2026
8 min read ·Lesson 101 of 109
In this post

How PHP Represents Dates and Times In simple terms: Applications constantly work with dates and times — order dates, due dates, "posted 3 hours ago", age checks, and schedules. PHP provides functions

How PHP Represents Dates and Times

In simple terms: Applications constantly work with dates and times — order dates, due dates, "posted 3 hours ago", age checks, and schedules. PHP provides functions to get the current time, display dates in any format, convert text like "next Monday" into dates, and calculate differences.

Technically: PHP offers two approaches:

ApproachMain ToolsBest For
Procedural, timestamp-basedtime(), date(), mktime(), strtotime(), checkdate()Quick formatting and simple calculations
Object-orientedDateTimeImmutable, DateTime, DateInterval, DatePeriod, DateTimeZoneCalculations, time zones, and any non-trivial logic

This lesson covers the fundamentals and the procedural functions. Date Formatting, DateTime Class, and Timezones cover the rest of this section.


Unix Timestamps

A Unix timestamp is the number of seconds that have passed since 1 January 1970, 00:00:00 UTC (the "Unix epoch"). It is a single integer that identifies a moment in time, independent of time zones.

<?php
$now = time();

var_dump(is_int($now));
echo "Seconds since 1970: " . $now . "\n";

Output (the number depends on when you run it)

bool(true)
Seconds since 1970: 1792054800

Why Timestamps Are Useful

  • They are easy to compare: a larger timestamp is a later moment.
  • Differences are simple arithmetic: $end - $start gives seconds.
  • They are independent of the time zone; the same timestamp represents the same instant everywhere.

Their limitation: a timestamp alone does not say how a person in a particular place should see that moment. Converting to a readable date always involves a time zone.

Year 2038: On old 32-bit systems, timestamps overflowed on 19 January 2038. Modern PHP on 64-bit systems uses 64-bit integers, which covers billions of years. The DateTime classes do not have this limit on any platform.


Setting the Default Time Zone

Functions such as date() convert timestamps using the default time zone. Set it explicitly so results do not depend on server configuration:

<?php
date_default_timezone_set('Asia/Kolkata');

echo date_default_timezone_get() . "\n";

Output

Asia/Kolkata

The default can also be set in php.ini with date.timezone = Asia/Kolkata. If neither is set, PHP uses UTC. Time zones are covered in detail in Timezones.


date() — Formatting a Timestamp

Syntax

date(string $format, ?int $timestamp = null): string

Without a timestamp, date() formats the current time.

Example

<?php
date_default_timezone_set('Asia/Kolkata');

$timestamp = 1792054800;   // 15 October 2026, 14:30 in India

echo date('Y-m-d H:i:s', $timestamp) . "\n";
echo date('d/m/Y', $timestamp) . "\n";
echo date('l, jS F Y', $timestamp) . "\n";
echo date('h:i A', $timestamp) . "\n";

Output

2026-10-15 14:30:00
15/10/2026
Thursday, 15th October 2026
02:30 PM

Each letter in the format string stands for a part of the date (Y = four-digit year, m = month with leading zero, l = weekday name, A = AM/PM, and so on). Characters that are not format letters, such as -, /, :, and spaces, are copied as they are. The full list is in Date Formatting.


mktime() — Creating a Timestamp From Parts

Syntax

mktime(int $hour, ?int $minute = null, ?int $second = null, ?int $month = null, ?int $day = null, ?int $year = null): int|false
<?php
date_default_timezone_set('Asia/Kolkata');

$timestamp = mktime(14, 30, 0, 10, 15, 2026);

echo $timestamp . "\n";
echo date('D, d M Y H:i', $timestamp) . "\n";

echo date('Y-m-d', mktime(0, 0, 0, 13, 1, 2026)) . "\n";
echo date('Y-m-d', mktime(0, 0, 0, 3, 0, 2028)) . "\n";

Output

1792054800
Thu, 15 Oct 2026 14:30
2027-01-01
2028-02-29
  • The order of arguments is hour, minute, second, month, day, year — easy to mix up.
  • Out-of-range values roll over: month 13 of 2026 becomes January 2027, and day 0 of March becomes the last day of February — a common trick for finding the last day of a month (2028 is a leap year).
  • The parts are interpreted in the default time zone.

strtotime() — Converting Text to a Timestamp

strtotime() understands a wide range of English date expressions, both absolute and relative.

Syntax

strtotime(string $datetime, ?int $baseTimestamp = null): int|false

Relative expressions are calculated from $baseTimestamp (default: now).

Example

<?php
date_default_timezone_set('Asia/Kolkata');

$base = mktime(14, 30, 0, 10, 15, 2026);   // Thursday, 15 October 2026, 14:30

$expressions = [
    '2026-12-25',
    '+7 days',
    '+1 week 2 days',
    'next monday',
    'last day of february 2028',
    'first monday of january 2027',
    'tomorrow 09:00',
];

foreach ($expressions as $expression) {
    $result = strtotime($expression, $base);
    echo str_pad($expression, 30) . date('D, d M Y H:i', $result) . "\n";
}

var_dump(strtotime('not a real date'));

Output

2026-12-25                    Fri, 25 Dec 2026 00:00
+7 days                       Thu, 22 Oct 2026 14:30
+1 week 2 days                Sat, 24 Oct 2026 14:30
next monday                   Mon, 19 Oct 2026 00:00
last day of february 2028     Tue, 29 Feb 2028 00:00
first monday of january 2027  Mon, 04 Jan 2027 00:00
tomorrow 09:00                Fri, 16 Oct 2026 09:00
bool(false)

Points to Notice

  • Pure relative amounts (+7 days, +1 week 2 days) keep the base time of day.
  • Expressions that name a date (2026-12-25, february 2028), a weekday (next monday), or tomorrow reset the time to midnight, unless a time is given (tomorrow 09:00).
  • last day of and first monday of select a specific day within the named month.
  • Unrecognized text returns false — always check the result before using it.

strtotime() is very convenient for fixed, program-defined expressions. For user input, parse with an explicit format instead (DateTimeImmutable::createFromFormat()), because ambiguous input like 01/02/2026 is interpreted in US order (month/day) by strtotime(), which most Indian users would not expect.


checkdate() — Validating a Date

<?php
var_dump(checkdate(2, 29, 2027));
var_dump(checkdate(2, 29, 2028));
var_dump(checkdate(4, 31, 2026));

Output

bool(false)
bool(true)
bool(false)

checkdate($month, $day, $year) confirms that a combination of numbers forms a real calendar date — useful when a form uses separate fields for day, month, and year.


Calculating With Timestamps

<?php
date_default_timezone_set('Asia/Kolkata');

$today = strtotime('2026-10-15');
$festival = strtotime('2026-12-25');

$days = intdiv($festival - $today, 86400);

echo "Days until 25 December: $days\n";

Output

Days until 25 December: 71

Subtracting timestamps gives seconds; dividing by 86400 (seconds per day) gives days. This works reliably in time zones without daylight saving time, such as India. In zones with daylight saving time, some days are 23 or 25 hours long, so dividing by 86400 can be off by one. DateTimeImmutable::diff() handles this correctly (see DateTime Class).


Measuring Elapsed Time

To measure how long code takes to run, use hrtime(), a high-resolution monotonic clock that is not affected by changes to the system clock:

<?php
$start = hrtime(true);

$sum = 0;
for ($i = 0; $i < 1_000_000; $i++) {
    $sum += $i;
}

$elapsedMs = (hrtime(true) - $start) / 1_000_000;

printf("Sum: %d, took %.2f ms\n", $sum, $elapsedMs);

Output (the time varies between runs and machines)

Sum: 499999500000, took 6.42 ms

hrtime(true) returns nanoseconds as an integer. microtime(true) (seconds as a float) is also common, but it follows the system clock, which can jump.


Function Overview

FunctionPurpose
time()Current Unix timestamp
date($format, $timestamp)Format a timestamp in the default time zone
gmdate($format, $timestamp)Format a timestamp in UTC
mktime(...)Timestamp from date and time parts
strtotime($text, $base)Timestamp from an English date expression
checkdate($m, $d, $y)Validate a calendar date
date_default_timezone_set() / _get()Set or read the default time zone
hrtime() / microtime()High-resolution timing

Practical Example: Order Delivery Estimate

<?php
date_default_timezone_set('Asia/Kolkata');

function estimateDelivery(int $orderTimestamp, int $businessDays): string
{
    $cutoffHour = 15;
    $date = $orderTimestamp;

    if ((int) date('G', $date) >= $cutoffHour) {
        $date = strtotime('tomorrow', $date);
    }

    $added = 0;
    while ($added < $businessDays) {
        $date = strtotime('+1 day', $date);
        if ((int) date('N', $date) < 7) {   // Monday (1) to Saturday (6)
            $added++;
        }
    }

    return date('l, j F', $date);
}

$orderTime = mktime(16, 10, 0, 10, 15, 2026);   // Thursday 4:10 PM

echo "Ordered: " . date('D, d M Y g:i A', $orderTime) . "\n";
echo "Expected delivery: " . estimateDelivery($orderTime, 3) . "\n";

Output

Ordered: Thu, 15 Oct 2026 4:10 PM
Expected delivery: Tuesday, 20 October

Step-by-Step Explanation

  1. Orders placed at or after 3 PM (G = hour without leading zero) are treated as if placed the next day, so processing starts on Friday.
  2. The loop adds one day at a time and counts only Monday to Saturday (N = ISO day number, where 7 is Sunday).
  3. Starting from Friday: Saturday (1), Sunday (skipped), Monday (2), Tuesday (3) → Tuesday, 20 October.

A real system would also skip public holidays, which can be stored in an array of dates and checked in the loop.


Common Mistakes

Relying on the Server's Default Time Zone

Effect: Dates differ between development and production servers.

Fix: Set date.timezone in php.ini or call date_default_timezone_set().

Mixing Up mktime() Argument Order

Effect: Month and day are swapped, or wrong dates are created.

Fix: Remember hour, minute, second, month, day, year — or use DateTimeImmutable.

Using strtotime() on User Input

Effect: 01/02/2026 becomes 2 January (US order) instead of 1 February.

Fix: Parse user input with an explicit format using createFromFormat().

Not Checking for false

Effect: date('Y-m-d', false) silently formats the epoch: 1970-01-01.

Fix: Check strtotime() results with === false.

Dividing by 86400 in DST Time Zones

Effect: Off-by-one errors around daylight saving changes.

Fix: Use DateTimeImmutable::diff().


Best Practices

  • Always set an explicit default time zone.
  • Use timestamps for storage and comparison, and format them only for display.
  • Use strtotime() for fixed expressions in code, not for parsing user input.
  • Prefer DateTimeImmutable for calculations, time zones, and parsing.
  • Validate user-entered dates with checkdate() or createFromFormat().

Official reference: https://www.php.net/manual/en/function.date.php

0 Comments

Reviewed before they appear

No comments yet.

PHP
PHP Home PHP Switch PHP Match Alternative Syntax PHP Loops While Loop Do While Loop For Loop Foreach Loop Nested Loops Break Statement PHP Home PHP Intro PHP Install PHP Built-in Web Server PHP Syntax PHP Tags PHP and HTML PHP Comments PHP Multiline Comments PHP Variables Variables Scope PHP Casting Logical Operators Null Coalescing Operator Spaceship Operator Operator Precedence Continue Statement Modify Strings PHP If...Else...Elseif PHP If Modify Strings PHP If Operators PHP Functions Concatenate Strings PHP If...Else Slicing Strings User-defined Functions Slicing Strings PHP Shorthand if Escape Characters Default Argument Values PHP Nested if Pass by Reference String Interpolation Named Arguments PHP File Upload Variadic Functions Return Values Search in Strings Multibyte Strings Type Declarations in Functions PHP Numbers PHP Math PHP Floats PHP Random Numbers PHP Constants PHP Properties PHP Methods PHP Constructor Constructor Property Promotion PHP Cookies PHP Destructor PHP Access Modifiers Readonly Properties PHP Sessions PHP Inheritance Method Overriding PHP Filters The final Keyword CSRF Protection PHP Filters Advanced Session Security Secure Cookies PHP Magic Constants File Upload Security PHP Callback Functions PHP Operators Filesystem Security PHP JSON Arithmetic Operators Error Reporting in Production Hiding PHP Assignment Operators PHP Configuration (php.ini) Comparison Operators PHP Command Line (CLI) PHP Exceptions Increment / Decrement Operators Migrating to PHP 8 PHP Form Validation PHP Form Required PHP Form URL/E-mail Error Handling Form Input Sanitizing Escaping Output (htmlspecialchars) Custom Error Handler Checkbox, Radio and Select Inputs Sticky Forms PHP Form Complete PHP Date and Time Date Formatting Error Logging HTTP Headers and Redirects Output Buffering Sending Email PHP cURL Consuming REST APIs PHP Generators
Ask about this post
AI Ask about this post

Ask questions about PHP Date and Time and get answers drawn from it.

Signed-in readers only.