PHP getdate() 函数

getdate() 函数返回一个包含日期时间信息的关联数组,这些信息对应于指定的 Unix 时间戳。

注意:此函数返回的数组包含日期和时间的各个组成部分,便于分别访问和处理。

语法

getdate(?int $timestamp = null): array

参数

参数 类型 描述
$timestamp int|null 可选。Unix时间戳。如果未指定或为null,则使用当前时间。

返回值

返回一个包含以下键的关联数组:

键名 类型 描述
seconds int 秒数(0-59)
minutes int 分钟数(0-59)
hours int 小时数(0-23)
mday int 月份中的第几天(1-31)
wday int 星期几的数字表示(0=星期日,6=星期六)
mon int 月份(1-12)
year int 年份(4位数)
yday int 一年中的第几天(0-365)
weekday string 星期几的完整文本表示(Sunday 到 Saturday)
month string 月份的完整文本表示(January 到 December)
0 int Unix时间戳(自Unix纪元以来的秒数)

示例

示例 1:基本用法 - 获取当前日期时间信息

<?php
// 设置时区
date_default_timezone_set('Asia/Shanghai');

// 获取当前日期时间信息
$dateInfo = getdate();

echo "当前日期时间信息:\n\n";

// 输出所有信息
foreach ($dateInfo as $key => $value) {
    echo str_pad($key, 10) . ": " . $value . "\n";
}

echo "\n格式化输出:\n";
echo "今天是 " . $dateInfo['year'] . "年" . $dateInfo['mon'] . "月" . $dateInfo['mday'] . "日\n";
echo "星期" . $dateInfo['weekday'] . " (" . $dateInfo['wday'] . ")\n";
echo "时间: " . str_pad($dateInfo['hours'], 2, '0', STR_PAD_LEFT) . ":" .
    str_pad($dateInfo['minutes'], 2, '0', STR_PAD_LEFT) . ":" .
    str_pad($dateInfo['seconds'], 2, '0', STR_PAD_LEFT) . "\n";
echo "这是一年中的第 " . ($dateInfo['yday'] + 1) . " 天\n";
echo "Unix时间戳: " . $dateInfo[0] . "\n";
?>
                            

输出:


当前日期时间信息:

seconds  : 45
minutes  : 30
hours    : 14
mday     : 25
wday     : 1
mon      : 12
year     : 2023
yday     : 358
weekday  : Monday
month    : December
0        : 1703500245

格式化输出:
今天是 2023年12月25日
星期Monday (1)
时间: 14:30:45
这是一年中的第 359 天
Unix时间戳: 1703500245
                            
示例 2:处理特定时间戳

<?php
date_default_timezone_set('UTC');

// 定义几个重要的时间戳
$timestamps = [
    'Unix纪元' => 0,                    // 1970-01-01 00:00:00 UTC
    '2000年问题' => 946684800,          // 2000-01-01 00:00:00 UTC
    'PHP 5.0发布' => 1104537600,        // 2005-01-01 00:00:00 UTC
    'iPhone发布' => 1167609600,         // 2007-01-09 00:00:00 UTC
    '现在' => time(),                   // 当前时间
    '2038年问题' => 2147483647,         // 2038-01-19 03:14:07 UTC
    '未来日期' => 2556057599,           // 2050-12-31 23:59:59 UTC
    '历史日期' => -62135596800,         // 0000-01-01 00:00:00 UTC
];

foreach ($timestamps as $name => $timestamp) {
    $dateInfo = getdate($timestamp);

    echo $name . " (" . $timestamp . "):\n";
    echo "  日期: " . $dateInfo['year'] . "-" .
        str_pad($dateInfo['mon'], 2, '0', STR_PAD_LEFT) . "-" .
        str_pad($dateInfo['mday'], 2, '0', STR_PAD_LEFT) . "\n";
    echo "  时间: " . str_pad($dateInfo['hours'], 2, '0', STR_PAD_LEFT) . ":" .
        str_pad($dateInfo['minutes'], 2, '0', STR_PAD_LEFT) . ":" .
        str_pad($dateInfo['seconds'], 2, '0', STR_PAD_LEFT) . "\n";
    echo "  星期: " . $dateInfo['weekday'] . " (" . $dateInfo['wday'] . ")\n";

    // 检查是否支持64位时间戳
    if ($timestamp < 0 && PHP_INT_SIZE == 4) {
        echo "  注意:在32位系统上,负时间戳可能无法正确处理\n";
    }

    echo "\n";
}

// 使用strtotime转换的时间戳
echo "使用strtotime的时间戳:\n";
$christmas2023 = strtotime('2023-12-25 00:00:00');
$dateInfo = getdate($christmas2023);

echo "圣诞节2023: " . $dateInfo['year'] . "-" . $dateInfo['mon'] . "-" . $dateInfo['mday'] . "\n";
echo "星期: " . $dateInfo['weekday'] . "\n";
echo "一年中的第 " . ($dateInfo['yday'] + 1) . " 天\n";
?>
                            

输出:


Unix纪元 (0):
  日期: 1970-01-01
  时间: 00:00:00
  星期: Thursday (4)

2000年问题 (946684800):
  日期: 2000-01-01
  时间: 00:00:00
  星期: Saturday (6)

PHP 5.0发布 (1104537600):
  日期: 2005-01-01
  时间: 00:00:00
  星期: Saturday (6)

iPhone发布 (1167609600):
  日期: 2007-01-09
  时间: 00:00:00
  星期: Tuesday (2)

现在 (1703500245):
  日期: 2023-12-25
  时间: 14:30:45
  星期: Monday (1)

2038年问题 (2147483647):
  日期: 2038-01-19
  时间: 03:14:07
  星期: Tuesday (2)

未来日期 (2556057599):
  日期: 2050-12-31
  时间: 23:59:59
  星期: Saturday (6)

历史日期 (-62135596800):
  日期: 0-1-1
  时间: 00:00:00
  星期: Monday (1)
  注意:在32位系统上,负时间戳可能无法正确处理

使用strtotime的时间戳:
圣诞节2023: 2023-12-25
星期: Monday
一年中的第 359 天
                            
示例 3:实际应用 - 日期计算和验证

<?php
/**
 * 日期工具类 - 使用getdate进行各种日期计算
 */
class DateCalculator {

    /**
     * 计算两个日期之间的天数差
     */
    public static function daysBetween($timestamp1, $timestamp2): int {
        $date1 = getdate($timestamp1);
        $date2 = getdate($timestamp2);

        // 使用yday计算(考虑闰年)
        $year1 = $date1['year'];
        $year2 = $date2['year'];

        // 计算两个日期之间的天数
        $days = abs($date2[0] - $date1[0]) / 86400;

        return (int)$days;
    }

    /**
     * 检查日期是否为周末
     */
    public static function isWeekend($timestamp): bool {
        $date = getdate($timestamp);
        return $date['wday'] === 0 || $date['wday'] === 6;
    }

    /**
     * 获取下一个工作日
     */
    public static function nextBusinessDay($timestamp): int {
        $date = getdate($timestamp);
        $nextDay = $timestamp;

        do {
            $nextDay += 86400; // 加一天
            $nextDate = getdate($nextDay);
        } while ($nextDate['wday'] === 0 || $nextDate['wday'] === 6);

        return $nextDay;
    }

    /**
     * 计算年龄
     */
    public static function calculateAge($birthTimestamp): int {
        $now = getdate();
        $birth = getdate($birthTimestamp);

        $age = $now['year'] - $birth['year'];

        // 如果生日还没到,年龄减1
        if ($now['mon'] < $birth['mon'] ||
            ($now['mon'] == $birth['mon'] && $now['mday'] < $birth['mday'])) {
            $age--;
        }

        return $age;
    }

    /**
     * 验证日期是否有效
     */
    public static function isValidDate($year, $month, $day): bool {
        // 使用mktime创建时间戳,然后使用getdate验证
        $timestamp = mktime(0, 0, 0, $month, $day, $year);
        $date = getdate($timestamp);

        return $date['year'] == $year &&
            $date['mon'] == $month &&
            $date['mday'] == $day;
    }

    /**
     * 获取月份信息
     */
    public static function getMonthInfo($year, $month): array {
        $firstDay = mktime(0, 0, 0, $month, 1, $year);
        $lastDay = mktime(23, 59, 59, $month + 1, 0, $year);

        $firstDate = getdate($firstDay);
        $lastDate = getdate($lastDay);

        return [
            'month_name' => $firstDate['month'],
            'first_day' => $firstDate,
            'last_day' => $lastDate,
            'total_days' => $lastDate['mday'],
            'first_weekday' => $firstDate['wday'],
            'last_weekday' => $lastDate['wday'],
            'weeks_in_month' => ceil(($lastDate['mday'] + $firstDate['wday']) / 7)
        ];
    }

    /**
     * 生成日历
     */
    public static function generateCalendar($year, $month): array {
        $monthInfo = self::getMonthInfo($year, $month);
        $calendar = [];

        $day = 1;
        for ($week = 0; $week < $monthInfo['weeks_in_month']; $week++) {
            $calendar[$week] = [];

            for ($weekday = 0; $weekday < 7; $weekday++) {
                if (($week == 0 && $weekday < $monthInfo['first_weekday']) ||
                    $day > $monthInfo['total_days']) {
                    $calendar[$week][$weekday] = null;
                } else {
                    $calendar[$week][$weekday] = $day;
                    $day++;
                }
            }
        }

        return $calendar;
    }
}

// 使用示例
date_default_timezone_set('Asia/Shanghai');

echo "日期计算和验证工具\n\n";

// 1. 计算天数差
$date1 = strtotime('2023-01-01');
$date2 = strtotime('2023-12-31');
$daysDiff = DateCalculator::daysBetween($date1, $date2);
echo "1. 2023-01-01 到 2023-12-31 的天数差: " . $daysDiff . " 天\n";

// 2. 检查周末
$testDate = strtotime('2023-12-25'); // 圣诞节
echo "2. 2023-12-25 是周末吗? " . (DateCalculator::isWeekend($testDate) ? '是' : '否') . "\n";

// 3. 获取下一个工作日
$nextBusiness = DateCalculator::nextBusinessDay($testDate);
$nextBusinessDate = getdate($nextBusiness);
echo "3. 2023-12-25 的下一个工作日: " .
    $nextBusinessDate['year'] . "-" . $nextBusinessDate['mon'] . "-" . $nextBusinessDate['mday'] . "\n";

// 4. 计算年龄
$birthDate = strtotime('1990-06-15');
$age = DateCalculator::calculateAge($birthDate);
echo "4. 1990-06-15 出生的人现在年龄: " . $age . " 岁\n";

// 5. 验证日期
echo "5. 日期验证:\n";
echo "   2023-02-29 是否有效? " . (DateCalculator::isValidDate(2023, 2, 29) ? '是' : '否') . "\n";
echo "   2024-02-29 是否有效? " . (DateCalculator::isValidDate(2024, 2, 29) ? '是' : '否') . "\n";

// 6. 获取月份信息
echo "\n6. 2023年12月信息:\n";
$monthInfo = DateCalculator::getMonthInfo(2023, 12);
echo "   月份名称: " . $monthInfo['month_name'] . "\n";
echo "   总天数: " . $monthInfo['total_days'] . "\n";
echo "   第一天星期: " . $monthInfo['first_day']['weekday'] . " (" . $monthInfo['first_day']['wday'] . ")\n";
echo "   最后一天星期: " . $monthInfo['last_day']['weekday'] . " (" . $monthInfo['last_day']['wday'] . ")\n";
echo "   周数: " . $monthInfo['weeks_in_month'] . "\n";

// 7. 生成日历
echo "\n7. 2023年12月日历:\n";
$calendar = DateCalculator::generateCalendar(2023, 12);

$weekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
echo str_pad("", 25, "-") . "\n";
echo " " . implode(" ", $weekDays) . "\n";
echo str_pad("", 25, "-") . "\n";

foreach ($calendar as $week) {
    $weekOutput = [];
    foreach ($week as $day) {
        $weekOutput[] = $day ? str_pad($day, 3, ' ', STR_PAD_BOTH) : "   ";
    }
    echo implode(" ", $weekOutput) . "\n";
}
echo str_pad("", 25, "-") . "\n";
?>
                            

输出:


日期计算和验证工具

1. 2023-01-01 到 2023-12-31 的天数差: 364 天
2. 2023-12-25 是周末吗? 否
3. 2023-12-25 的下一个工作日: 2023-12-26
4. 1990-06-15 出生的人现在年龄: 33 岁
5. 日期验证:
   2023-02-29 是否有效? 否
   2024-02-29 是否有效? 是

6. 2023年12月信息:
   月份名称: December
   总天数: 31
   第一天星期: Friday (5)
   最后一天星期: Sunday (0)
   周数: 6

7. 2023年12月日历:
-------------------------
 Sun Mon Tue Wed Thu Fri Sat
-------------------------
                1   2   3   4
  5   6   7   8   9  10  11
 12  13  14  15  16  17  18
 19  20  21  22  23  24  25
 26  27  28  29  30  31
-------------------------
                            
getdate() 与 date() 对比
getdate() 函数
  • 返回值:关联数组
  • 使用场景:需要分别访问日期时间各部分
  • 示例:
    
    $date = getdate();
    $hour = $date['hours'];
    $minute = $date['minutes'];
                                                
  • 优点:一次性获取所有日期时间组件
  • 缺点:需要记忆数组键名
date() 函数
  • 返回值:格式化字符串
  • 使用场景:需要特定格式的日期时间字符串
  • 示例:
    
    $time = date('H:i:s');
    $date = date('Y-m-d');
                                                
  • 优点:灵活格式化输出
  • 缺点:每次只能获取一种格式
选择建议:当需要同时获取多个日期时间组件时使用 getdate(),当只需要特定格式的字符串时使用 date()
时间戳处理说明
32位系统限制

范围:1901-12-13 到 2038-01-19
最大值:2147483647
最小值:-2147483648

64位系统优势

范围:约公元前292亿年到公元292亿年
无2038年问题
支持负时间戳

时间戳来源
  • time() - 当前时间
  • strtotime() - 字符串转换
  • mktime() - 组件创建
  • 自定义整数值
常见错误和注意事项
1. 时区设置不正确

<?php
// 错误:未设置时区,使用服务器默认时区
$dateInfo = getdate();
echo "当前时间: " . $dateInfo['hours'] . ":" . $dateInfo['minutes'] . "\n";

// 正确:明确设置时区
date_default_timezone_set('Asia/Shanghai');
$dateInfo = getdate();
echo "北京时间: " . $dateInfo['hours'] . ":" . $dateInfo['minutes'] . "\n";
?>
                            
2. 数组键名混淆

<?php
// 错误:混淆了wday和mday
$dateInfo = getdate();
echo "今天是月份的第 " . $dateInfo['wday'] . " 天?\n"; // 错误!wday是星期几

// 正确:使用正确的键名
echo "今天是月份的第 " . $dateInfo['mday'] . " 天\n"; // 正确
echo "今天是星期 " . $dateInfo['wday'] . "\n"; // 正确
?>
                            
3. 处理超出范围的时间戳

<?php
// 在32位系统上,大时间戳可能产生错误
$largeTimestamp = 3000000000; // 超过32位最大值

// 检查系统类型
if (PHP_INT_SIZE == 4) { // 32位系统
    echo "运行在32位系统上\n";
    if ($largeTimestamp > 2147483647) {
        echo "时间戳超出范围,可能产生错误\n";
    }
} else { // 64位系统
    $dateInfo = getdate($largeTimestamp);
    echo "日期: " . $dateInfo['year'] . "-" . $dateInfo['mon'] . "-" . $dateInfo['mday'] . "\n";
}
?>
                            

注意事项

  • 时区设置:使用 getdate() 前务必使用 date_default_timezone_set() 设置正确的时区。
  • 键名记忆:注意区分 wday(星期几)和 mday(月份中的第几天)。
  • 数组索引:数组中的 0 键存储的是Unix时间戳本身。
  • yday起始:yday 从0开始计数,表示一年中的第几天(0-365)。
  • 性能考虑:频繁调用 getdate() 会产生性能开销,考虑缓存结果。
  • 2038年问题:在32位系统上,时间戳超过2147483647会导致溢出错误。
  • 负时间戳:负时间戳表示1970年之前的日期,但在32位系统上可能无法正确处理。
  • 夏令时:getdate() 考虑夏令时设置,返回的时间会相应调整。

相关函数

date()

格式化Unix时间戳为日期时间字符串

time()

返回当前的Unix时间戳

strtotime()

将英文文本日期时间解析为Unix时间戳

mktime()

取得一个日期的Unix时间戳

localtime()

获取本地时间,返回索引数组

DateTime::getTimestamp()

面向对象风格的获取时间戳方法