Date and Time Functions Reference
Introduction to PHP Date and Time
PHP provides extensive support for date and time manipulation through built-in functions and the DateTime class. This reference covers both procedural functions and object-oriented approaches to working with dates and times.
Basic Date and Time Functions
date() - Format a Date
<?php
// Current date and time
echo date('Y-m-d H:i:s'); // Output: 2023-01-15 14:30:25
// Various formats
echo date('d/m/Y'); // Output: 15/01/2023
echo date('F j, Y'); // Output: January 15, 2023
echo date('l, F j, Y'); // Output: Sunday, January 15, 2023
echo date('g:i A'); // Output: 2:30 PM
// Format specific timestamp
$timestamp = 1642262400;
echo date('Y-m-d', $timestamp); // Output: 2022-01-15
// Common format patterns
$formats = [
'Y-m-d' => '2023-01-15',
'Y-m-d H:i:s' => '2023-01-15 14:30:25',
'd/m/Y' => '15/01/2023',
'F j, Y' => 'January 15, 2023',
'M j, Y' => 'Jan 15, 2023',
'l, F j, Y' => 'Sunday, January 15, 2023',
'D, M j, Y' => 'Sun, Jan 15, 2023',
'g:i A' => '2:30 PM',
'H:i:s' => '14:30:25',
'c' => '2023-01-15T14:30:25+00:00', // ISO 8601
'r' => 'Sun, 15 Jan 2023 14:30:25 +0000', // RFC 2822
'U' => '1673794225' // Unix timestamp
];
foreach ($formats as $format => $example) {
echo "$format: " . date($format) . "\n";
}
?>
time() and mktime() - Get Timestamps
<?php
// Current Unix timestamp
$now = time();
echo $now; // Output: 1673794225
// Create timestamp from date components
$timestamp = mktime(14, 30, 25, 1, 15, 2023); // hour, minute, second, month, day, year
echo date('Y-m-d H:i:s', $timestamp); // Output: 2023-01-15 14:30:25
// First day of current month
$firstDay = mktime(0, 0, 0, date('n'), 1, date('Y'));
echo date('Y-m-d', $firstDay);
// Last day of current month
$lastDay = mktime(0, 0, 0, date('n') + 1, 0, date('Y'));
echo date('Y-m-d', $lastDay);
// Calculate age
function calculateAge($birthDate) {
$birth = strtotime($birthDate);
$today = time();
$age = floor(($today - $birth) / (365.25 * 24 * 3600));
return $age;
}
echo calculateAge('1990-05-15'); // Output: 32 (approximately)
// Days until next birthday
function daysUntilBirthday($birthDate) {
$birth = DateTime::createFromFormat('Y-m-d', $birthDate);
$today = new DateTime();
$nextBirthday = clone $birth;
$nextBirthday->setDate($today->format('Y'), $birth->format('m'), $birth->format('d'));
if ($nextBirthday < $today) {
$nextBirthday->modify('+1 year');
}
return $today->diff($nextBirthday)->days;
}
echo daysUntilBirthday('1990-05-15');
?>
DateTime Class
Creating DateTime Objects
<?php
// Create DateTime objects
$now = new DateTime();
echo $now->format('Y-m-d H:i:s');
// From string
$date1 = new DateTime('2023-01-15');
$date2 = new DateTime('2023-01-15 14:30:25');
$date3 = new DateTime('next Monday');
$date4 = new DateTime('+1 week');
// From format
$date5 = DateTime::createFromFormat('d/m/Y', '15/01/2023');
$date6 = DateTime::createFromFormat('Y-m-d H:i:s', '2023-01-15 14:30:25');
// From timestamp
$date7 = new DateTime('@1673794225');
// With timezone
$date8 = new DateTime('2023-01-15 14:30:25', new DateTimeZone('America/New_York'));
// Current date in different timezone
$utc = new DateTime('now', new DateTimeZone('UTC'));
$ny = new DateTime('now', new DateTimeZone('America/New_York'));
$tokyo = new DateTime('now', new DateTimeZone('Asia/Tokyo'));
echo "UTC: " . $utc->format('Y-m-d H:i:s T') . "\n";
echo "New York: " . $ny->format('Y-m-d H:i:s T') . "\n";
echo "Tokyo: " . $tokyo->format('Y-m-d H:i:s T') . "\n";
// Error handling
try {
$invalidDate = new DateTime('invalid date');
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
?>
DateTime Manipulation
<?php
$date = new DateTime('2023-01-15 14:30:25');
// Add time
$date->add(new DateInterval('P1D')); // Add 1 day
echo $date->format('Y-m-d H:i:s'); // Output: 2023-01-16 14:30:25
$date->add(new DateInterval('PT2H30M')); // Add 2 hours 30 minutes
echo $date->format('Y-m-d H:i:s'); // Output: 2023-01-16 17:00:25
// Subtract time
$date->sub(new DateInterval('P1W')); // Subtract 1 week
echo $date->format('Y-m-d H:i:s'); // Output: 2023-01-09 17:00:25
// Modify with string
$date = new DateTime('2023-01-15');
$date->modify('+1 day');
$date->modify('+2 hours');
$date->modify('next Monday');
$date->modify('last day of this month');
// Set specific values
$date->setDate(2023, 12, 25);
$date->setTime(10, 30, 0);
// Clone for immutable operations
$originalDate = new DateTime('2023-01-15');
$modifiedDate = clone $originalDate;
$modifiedDate->add(new DateInterval('P1D'));
echo "Original: " . $originalDate->format('Y-m-d') . "\n";
echo "Modified: " . $modifiedDate->format('Y-m-d') . "\n";
// DateTimeImmutable (PHP 5.5+)
$immutableDate = new DateTimeImmutable('2023-01-15');
$newDate = $immutableDate->add(new DateInterval('P1D'));
echo "Immutable: " . $immutableDate->format('Y-m-d') . "\n";
echo "New: " . $newDate->format('Y-m-d') . "\n";
?>
Date Intervals and Periods
<?php
// Create intervals
$interval1 = new DateInterval('P1Y2M3DT4H5M6S'); // 1 year, 2 months, 3 days, 4 hours, 5 minutes, 6 seconds
$interval2 = DateInterval::createFromDateString('1 day 2 hours');
// Calculate difference between dates
$date1 = new DateTime('2023-01-15');
$date2 = new DateTime('2023-02-20');
$diff = $date1->diff($date2);
echo $diff->format('%R%a days'); // Output: +36 days
echo $diff->format('%y years, %m months, %d days'); // Output: 0 years, 1 months, 5 days
// Properties of DateInterval
echo "Years: " . $diff->y . "\n";
echo "Months: " . $diff->m . "\n";
echo "Days: " . $diff->d . "\n";
echo "Hours: " . $diff->h . "\n";
echo "Minutes: " . $diff->i . "\n";
echo "Seconds: " . $diff->s . "\n";
echo "Total days: " . $diff->days . "\n";
echo "Inverted: " . ($diff->invert ? 'Yes' : 'No') . "\n";
// Date periods
$start = new DateTime('2023-01-01');
$interval = new DateInterval('P1D');
$end = new DateTime('2023-01-10');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $date) {
echo $date->format('Y-m-d') . "\n";
}
// Working days between two dates
function getWorkingDays(DateTime $start, DateTime $end) {
$workingDays = 0;
$period = new DatePeriod($start, new DateInterval('P1D'), $end);
foreach ($period as $date) {
$dayOfWeek = $date->format('N'); // 1 (Monday) to 7 (Sunday)
if ($dayOfWeek < 6) { // Monday to Friday
$workingDays++;
}
}
return $workingDays;
}
$start = new DateTime('2023-01-01');
$end = new DateTime('2023-01-31');
echo "Working days: " . getWorkingDays($start, $end);
?>
Timezone Handling
Working with Timezones
<?php
// Get available timezones
$timezones = DateTimeZone::listIdentifiers();
echo "Total timezones: " . count($timezones) . "\n";
// Timezone by region
$americaTimezones = DateTimeZone::listIdentifiers(DateTimeZone::AMERICA);
$europeTimezones = DateTimeZone::listIdentifiers(DateTimeZone::EUROPE);
// Create timezone objects
$utc = new DateTimeZone('UTC');
$newYork = new DateTimeZone('America/New_York');
$london = new DateTimeZone('Europe/London');
$tokyo = new DateTimeZone('Asia/Tokyo');
// Convert between timezones
$date = new DateTime('2023-01-15 12:00:00', $utc);
echo "UTC: " . $date->format('Y-m-d H:i:s T') . "\n";
$date->setTimezone($newYork);
echo "New York: " . $date->format('Y-m-d H:i:s T') . "\n";
$date->setTimezone($london);
echo "London: " . $date->format('Y-m-d H:i:s T') . "\n";
$date->setTimezone($tokyo);
echo "Tokyo: " . $date->format('Y-m-d H:i:s T') . "\n";
// Timezone information
$tz = new DateTimeZone('America/New_York');
$transitions = $tz->getTransitions();
$location = $tz->getLocation();
echo "Timezone: " . $tz->getName() . "\n";
echo "Country: " . $location['country_code'] . "\n";
echo "Latitude: " . $location['latitude'] . "\n";
echo "Longitude: " . $location['longitude'] . "\n";
// DST transitions
$now = new DateTime();
$offset = $tz->getOffset($now);
echo "Current offset: " . ($offset / 3600) . " hours\n";
// Time zone abbreviations
echo "EST offset: " . timezone_offset_get(timezone_open('EST'), $now) / 3600 . " hours\n";
// Default timezone
date_default_timezone_set('America/New_York');
echo "Default timezone: " . date_default_timezone_get() . "\n";
echo "Current time: " . date('Y-m-d H:i:s T') . "\n";
?>
Timezone Conversion Utilities
<?php
class TimezoneConverter
{
public static function convertTime($time, $fromTz, $toTz)
{
$date = new DateTime($time, new DateTimeZone($fromTz));
$date->setTimezone(new DateTimeZone($toTz));
return $date;
}
public static function getTimezoneOffset($timezone, $baseTimezone = 'UTC')
{
$base = new DateTime('now', new DateTimeZone($baseTimezone));
$target = new DateTime('now', new DateTimeZone($timezone));
return $base->getOffset() - $target->getOffset();
}
public static function getCurrentTimeInTimezone($timezone)
{
return new DateTime('now', new DateTimeZone($timezone));
}
public static function getTimezonesByOffset($offset)
{
$timezones = [];
$now = new DateTime();
foreach (DateTimeZone::listIdentifiers() as $timezone) {
$tz = new DateTimeZone($timezone);
if ($tz->getOffset($now) === $offset * 3600) {
$timezones[] = $timezone;
}
}
return $timezones;
}
}
// Usage examples
$converted = TimezoneConverter::convertTime('2023-01-15 12:00:00', 'UTC', 'America/New_York');
echo $converted->format('Y-m-d H:i:s T') . "\n";
$offset = TimezoneConverter::getTimezoneOffset('America/New_York');
echo "New York offset from UTC: " . ($offset / 3600) . " hours\n";
$currentNY = TimezoneConverter::getCurrentTimeInTimezone('America/New_York');
echo "Current time in NY: " . $currentNY->format('Y-m-d H:i:s T') . "\n";
$gmt5Timezones = TimezoneConverter::getTimezonesByOffset(-5);
print_r(array_slice($gmt5Timezones, 0, 5));
?>
Date Formatting and Parsing
Custom Formatting
<?php
// Custom date formatter class
class DateFormatter
{
private static $customFormats = [
'short' => 'M j, Y',
'medium' => 'F j, Y',
'long' => 'l, F j, Y',
'iso' => 'Y-m-d',
'rfc' => 'r',
'timestamp' => 'U'
];
public static function format($date, $format)
{
if (!$date instanceof DateTime) {
$date = new DateTime($date);
}
$formatString = self::$customFormats[$format] ?? $format;
return $date->format($formatString);
}
public static function relative($date)
{
if (!$date instanceof DateTime) {
$date = new DateTime($date);
}
$now = new DateTime();
$diff = $now->diff($date);
if ($diff->y > 0) {
return $diff->y . ' year' . ($diff->y > 1 ? 's' : '') . ' ago';
} elseif ($diff->m > 0) {
return $diff->m . ' month' . ($diff->m > 1 ? 's' : '') . ' ago';
} elseif ($diff->d > 0) {
return $diff->d . ' day' . ($diff->d > 1 ? 's' : '') . ' ago';
} elseif ($diff->h > 0) {
return $diff->h . ' hour' . ($diff->h > 1 ? 's' : '') . ' ago';
} elseif ($diff->i > 0) {
return $diff->i . ' minute' . ($diff->i > 1 ? 's' : '') . ' ago';
} else {
return 'just now';
}
}
public static function humanReadable($date)
{
if (!$date instanceof DateTime) {
$date = new DateTime($date);
}
$now = new DateTime();
$diff = $now->diff($date);
if ($diff->days === 0) {
return 'today';
} elseif ($diff->days === 1 && $diff->invert) {
return 'yesterday';
} elseif ($diff->days === 1 && !$diff->invert) {
return 'tomorrow';
} elseif ($diff->days < 7 && $diff->invert) {
return $date->format('l'); // Day name
} else {
return $date->format('M j');
}
}
}
// Usage
$date = new DateTime('2023-01-15');
echo DateFormatter::format($date, 'short') . "\n";
echo DateFormatter::format($date, 'medium') . "\n";
echo DateFormatter::format($date, 'long') . "\n";
$pastDate = new DateTime('-2 hours');
echo DateFormatter::relative($pastDate) . "\n";
$yesterday = new DateTime('-1 day');
echo DateFormatter::humanReadable($yesterday) . "\n";
?>
Parsing Different Date Formats
<?php
class DateParser
{
private static $formats = [
'Y-m-d',
'd/m/Y',
'm/d/Y',
'd-m-Y',
'm-d-Y',
'Y-m-d H:i:s',
'd/m/Y H:i:s',
'F j, Y',
'M j, Y',
'j F Y',
'j M Y'
];
public static function parse($dateString)
{
// Try each format until one works
foreach (self::$formats as $format) {
$date = DateTime::createFromFormat($format, $dateString);
if ($date !== false) {
return $date;
}
}
// Try strtotime as fallback
$timestamp = strtotime($dateString);
if ($timestamp !== false) {
return new DateTime("@$timestamp");
}
throw new InvalidArgumentException("Could not parse date: $dateString");
}
public static function parseMultiple(array $dateStrings)
{
$dates = [];
foreach ($dateStrings as $dateString) {
try {
$dates[] = self::parse($dateString);
} catch (InvalidArgumentException $e) {
$dates[] = null;
}
}
return $dates;
}
public static function validateDate($dateString, $format = 'Y-m-d')
{
$date = DateTime::createFromFormat($format, $dateString);
return $date && $date->format($format) === $dateString;
}
}
// Usage
$dates = [
'2023-01-15',
'15/01/2023',
'January 15, 2023',
'Jan 15, 2023',
'next Monday',
'+1 week'
];
foreach ($dates as $dateString) {
try {
$parsed = DateParser::parse($dateString);
echo "$dateString -> " . $parsed->format('Y-m-d') . "\n";
} catch (Exception $e) {
echo "$dateString -> Error: " . $e->getMessage() . "\n";
}
}
// Validation
$validDates = ['2023-01-15', '2023-02-30', '2023-13-01'];
foreach ($validDates as $date) {
$isValid = DateParser::validateDate($date);
echo "$date: " . ($isValid ? 'Valid' : 'Invalid') . "\n";
}
?>
Date Calculations and Utilities
Common Date Calculations
<?php
class DateCalculations
{
public static function getQuarter(DateTime $date)
{
$month = (int) $date->format('n');
return ceil($month / 3);
}
public static function getWeekOfYear(DateTime $date)
{
return (int) $date->format('W');
}
public static function getDayOfYear(DateTime $date)
{
return (int) $date->format('z') + 1;
}
public static function isWeekend(DateTime $date)
{
$dayOfWeek = (int) $date->format('N');
return $dayOfWeek >= 6; // Saturday or Sunday
}
public static function isLeapYear($year)
{
return (bool) date('L', mktime(0, 0, 0, 1, 1, $year));
}
public static function getDaysInMonth($month, $year)
{
return (int) date('t', mktime(0, 0, 0, $month, 1, $year));
}
public static function getFirstDayOfMonth(DateTime $date)
{
return new DateTime($date->format('Y-m-01'));
}
public static function getLastDayOfMonth(DateTime $date)
{
return new DateTime($date->format('Y-m-t'));
}
public static function getNextWorkday(DateTime $date)
{
$nextDay = clone $date;
$nextDay->add(new DateInterval('P1D'));
while (self::isWeekend($nextDay)) {
$nextDay->add(new DateInterval('P1D'));
}
return $nextDay;
}
public static function getPreviousWorkday(DateTime $date)
{
$prevDay = clone $date;
$prevDay->sub(new DateInterval('P1D'));
while (self::isWeekend($prevDay)) {
$prevDay->sub(new DateInterval('P1D'));
}
return $prevDay;
}
public static function getWorkdaysBetween(DateTime $start, DateTime $end)
{
$workdays = 0;
$current = clone $start;
while ($current <= $end) {
if (!self::isWeekend($current)) {
$workdays++;
}
$current->add(new DateInterval('P1D'));
}
return $workdays;
}
public static function addWorkdays(DateTime $date, $days)
{
$result = clone $date;
$addedDays = 0;
while ($addedDays < $days) {
$result->add(new DateInterval('P1D'));
if (!self::isWeekend($result)) {
$addedDays++;
}
}
return $result;
}
}
// Usage examples
$date = new DateTime('2023-01-15');
echo "Quarter: " . DateCalculations::getQuarter($date) . "\n";
echo "Week of year: " . DateCalculations::getWeekOfYear($date) . "\n";
echo "Day of year: " . DateCalculations::getDayOfYear($date) . "\n";
echo "Is weekend: " . (DateCalculations::isWeekend($date) ? 'Yes' : 'No') . "\n";
echo "Is leap year: " . (DateCalculations::isLeapYear(2023) ? 'Yes' : 'No') . "\n";
echo "Days in month: " . DateCalculations::getDaysInMonth(1, 2023) . "\n";
$firstDay = DateCalculations::getFirstDayOfMonth($date);
echo "First day of month: " . $firstDay->format('Y-m-d') . "\n";
$lastDay = DateCalculations::getLastDayOfMonth($date);
echo "Last day of month: " . $lastDay->format('Y-m-d') . "\n";
$nextWorkday = DateCalculations::getNextWorkday($date);
echo "Next workday: " . $nextWorkday->format('Y-m-d') . "\n";
$start = new DateTime('2023-01-01');
$end = new DateTime('2023-01-31');
$workdays = DateCalculations::getWorkdaysBetween($start, $end);
echo "Workdays in January 2023: $workdays\n";
$futureWorkday = DateCalculations::addWorkdays($date, 10);
echo "10 workdays from now: " . $futureWorkday->format('Y-m-d') . "\n";
?>
Age and Duration Calculations
<?php
class AgeCalculator
{
public static function getExactAge(DateTime $birthDate, DateTime $currentDate = null)
{
if ($currentDate === null) {
$currentDate = new DateTime();
}
$diff = $birthDate->diff($currentDate);
return [
'years' => $diff->y,
'months' => $diff->m,
'days' => $diff->d,
'total_days' => $diff->days,
'hours' => $diff->h,
'minutes' => $diff->i,
'seconds' => $diff->s
];
}
public static function getAgeInYears(DateTime $birthDate, DateTime $currentDate = null)
{
if ($currentDate === null) {
$currentDate = new DateTime();
}
return $birthDate->diff($currentDate)->y;
}
public static function getAgeInDays(DateTime $birthDate, DateTime $currentDate = null)
{
if ($currentDate === null) {
$currentDate = new DateTime();
}
return $birthDate->diff($currentDate)->days;
}
public static function formatDuration(DateInterval $interval)
{
$parts = [];
if ($interval->y > 0) {
$parts[] = $interval->y . ' year' . ($interval->y > 1 ? 's' : '');
}
if ($interval->m > 0) {
$parts[] = $interval->m . ' month' . ($interval->m > 1 ? 's' : '');
}
if ($interval->d > 0) {
$parts[] = $interval->d . ' day' . ($interval->d > 1 ? 's' : '');
}
if ($interval->h > 0) {
$parts[] = $interval->h . ' hour' . ($interval->h > 1 ? 's' : '');
}
if ($interval->i > 0) {
$parts[] = $interval->i . ' minute' . ($interval->i > 1 ? 's' : '');
}
if ($interval->s > 0) {
$parts[] = $interval->s . ' second' . ($interval->s > 1 ? 's' : '');
}
if (empty($parts)) {
return '0 seconds';
}
if (count($parts) === 1) {
return $parts[0];
}
$last = array_pop($parts);
return implode(', ', $parts) . ' and ' . $last;
}
public static function getLifetimeStatistics(DateTime $birthDate)
{
$now = new DateTime();
$age = self::getExactAge($birthDate, $now);
return [
'age_in_years' => $age['years'],
'age_in_months' => ($age['years'] * 12) + $age['months'],
'age_in_days' => $age['total_days'],
'age_in_hours' => $age['total_days'] * 24,
'age_in_minutes' => $age['total_days'] * 24 * 60,
'age_in_seconds' => $age['total_days'] * 24 * 60 * 60,
'next_birthday' => self::getNextBirthday($birthDate),
'days_until_birthday' => self::getDaysUntilBirthday($birthDate)
];
}
private static function getNextBirthday(DateTime $birthDate)
{
$today = new DateTime();
$nextBirthday = new DateTime($today->format('Y') . '-' . $birthDate->format('m-d'));
if ($nextBirthday < $today) {
$nextBirthday->add(new DateInterval('P1Y'));
}
return $nextBirthday;
}
private static function getDaysUntilBirthday(DateTime $birthDate)
{
$nextBirthday = self::getNextBirthday($birthDate);
$today = new DateTime();
return $today->diff($nextBirthday)->days;
}
}
// Usage
$birthDate = new DateTime('1990-05-15');
$exactAge = AgeCalculator::getExactAge($birthDate);
echo "Exact age: " . AgeCalculator::formatDuration($birthDate->diff(new DateTime())) . "\n";
$ageInYears = AgeCalculator::getAgeInYears($birthDate);
echo "Age in years: $ageInYears\n";
$ageInDays = AgeCalculator::getAgeInDays($birthDate);
echo "Age in days: $ageInDays\n";
$stats = AgeCalculator::getLifetimeStatistics($birthDate);
print_r($stats);
?>
This comprehensive reference covers the essential date and time functions and classes in PHP, providing practical examples for real-world development scenarios.