PHP gmmktime() 函数

gmmktime() 函数返回一个日期的 Unix 时间戳,该函数将输入参数解释为 GMT(格林威治标准时间)时间。

注意:此函数与 mktime() 函数类似,但 mktime() 使用本地时间,而 gmmktime() 使用 GMT 时间。

语法

gmmktime(
    int $hour,
    ?int $minute = null,
    ?int $second = null,
    ?int $month = null,
    ?int $day = null,
    ?int $year = null
): int|false

参数

参数 类型 描述
$hour int 小时数(0-23)
$minute int|null 分钟数(0-59),可选,默认为当前分钟
$second int|null 秒数(0-59),可选,默认为当前秒
$month int|null 月份(1-12),可选,默认为当前月
$day int|null 日(1-31),可选,默认为当前日
$year int|null 年份(4位数),可选,默认为当前年

返回值

返回给定 GMT 日期时间的 Unix 时间戳(自 1970-01-01 00:00:00 GMT 以来的秒数)。如果参数无效,返回 false

示例

示例 1:基本用法 - 创建GMT时间戳

<?php
// 1. 创建特定GMT时间的时间戳
echo "1. 创建特定GMT时间的时间戳:\n";
$timestamp1 = gmmktime(12, 0, 0, 12, 25, 2023);
echo "   GMT 2023-12-25 12:00:00 的时间戳: " . $timestamp1 . "\n";
echo "   对应本地时间: " . date('Y-m-d H:i:s', $timestamp1) . "\n";
echo "   对应GMT时间: " . gmdate('Y-m-d H:i:s', $timestamp1) . "\n\n";

// 2. 使用部分参数(默认当前值)
echo "2. 使用部分参数:\n";
$timestamp2 = gmmktime(15, 30); // 只有小时和分钟,其他使用当前值
echo "   当前日期 GMT 15:30:00 的时间戳: " . $timestamp2 . "\n";
echo "   对应时间: " . gmdate('Y-m-d H:i:s', $timestamp2) . "\n\n";

// 3. 创建历史日期的时间戳
echo "3. 历史日期的时间戳:\n";
$timestamp3 = gmmktime(0, 0, 0, 1, 1, 1970); // Unix纪元
echo "   Unix纪元 (1970-01-01 00:00:00 GMT): " . $timestamp3 . "\n\n";

// 4. 创建未来日期的时间戳
echo "4. 未来日期的时间戳:\n";
$timestamp4 = gmmktime(23, 59, 59, 12, 31, 2030);
echo "   2030-12-31 23:59:59 GMT: " . $timestamp4 . "\n";
echo "   对应本地时间: " . date('Y-m-d H:i:s', $timestamp4) . "\n\n";

// 5. 与mktime()对比
echo "5. 与mktime()对比:\n";
date_default_timezone_set('Asia/Shanghai'); // 设置时区为北京时间

$gmtTimestamp = gmmktime(12, 0, 0, 12, 25, 2023);
$localTimestamp = mktime(12, 0, 0, 12, 25, 2023);

echo "   gmmktime(12,0,0,12,25,2023): " . $gmtTimestamp . " (" . gmdate('Y-m-d H:i:s', $gmtTimestamp) . " GMT)\n";
echo "   mktime(12,0,0,12,25,2023):   " . $localTimestamp . " (" . date('Y-m-d H:i:s', $localTimestamp) . " 本地时间)\n";
echo "   时间戳差异: " . ($localTimestamp - $gmtTimestamp) . " 秒 (8小时时差)\n";
?>
                            

输出:


1. 创建特定GMT时间的时间戳:
   GMT 2023-12-25 12:00:00 的时间戳: 1703505600
   对应本地时间: 2023-12-25 20:00:00
   对应GMT时间: 2023-12-25 12:00:00

2. 使用部分参数:
   当前日期 GMT 15:30:00 的时间戳: 1703511000
   对应时间: 2023-12-25 15:30:00

3. 历史日期的时间戳:
   Unix纪元 (1970-01-01 00:00:00 GMT): 0

4. 未来日期的时间戳:
   2030-12-31 23:59:59 GMT: 1924991999
   对应本地时间: 2031-01-01 07:59:59

5. 与mktime()对比:
   gmmktime(12,0,0,12,25,2023): 1703505600 (2023-12-25 12:00:00 GMT)
   mktime(12,0,0,12,25,2023):   1703534400 (2023-12-25 20:00:00 本地时间)
   时间戳差异: 28800 秒 (8小时时差)
                            
示例 2:处理时区和夏令时

<?php
/**
 * 时区转换工具类
 */
class TimezoneConverter {

    /**
     * 将本地时间转换为GMT时间戳
     */
    public static function localToGmtTimestamp($hour, $minute, $second, $month, $day, $year, $timezone): int {
        // 创建本地时间的DateTime对象
        $localDate = new DateTime("$year-$month-$day $hour:$minute:$second", new DateTimeZone($timezone));

        // 转换为GMT时区
        $localDate->setTimezone(new DateTimeZone('GMT'));

        // 返回Unix时间戳
        return $localDate->getTimestamp();
    }

    /**
     * 比较不同时区对时间戳的影响
     */
    public static function compareTimezones($hour, $minute, $second, $month, $day, $year): array {
        $timezones = [
            'GMT' => 'GMT',
            'Asia/Shanghai' => '北京时间 (UTC+8)',
            'America/New_York' => '纽约时间 (UTC-5/UTC-4)',
            'Europe/London' => '伦敦时间 (GMT/BST)',
            'Australia/Sydney' => '悉尼时间 (UTC+10/UTC+11)'
        ];

        $results = [];

        foreach ($timezones as $tz => $description) {
            if ($tz === 'GMT') {
                // 使用gmmktime获取GMT时间戳
                $timestamp = gmmktime($hour, $minute, $second, $month, $day, $year);
                $results[$description] = [
                    'timestamp' => $timestamp,
                    'gmt_time' => gmdate('Y-m-d H:i:s', $timestamp),
                    'local_time' => gmdate('Y-m-d H:i:s', $timestamp),
                    'timezone' => 'GMT'
                ];
            } else {
                $date = new DateTime("$year-$month-$day $hour:$minute:$second", new DateTimeZone($tz));
                $timestamp = $date->getTimestamp();
                $results[$description] = [
                    'timestamp' => $timestamp,
                    'gmt_time' => gmdate('Y-m-d H:i:s', $timestamp),
                    'local_time' => $date->format('Y-m-d H:i:s'),
                    'timezone' => $tz,
                    'offset' => $date->getOffset() / 3600
                ];
            }
        }

        return $results;
    }

    /**
     * 处理夏令时转换
     */
    public static function demonstrateDST(): array {
        $results = [];

        // 测试夏令时转换边界
        $dates = [
            '2023-03-12' => '美国夏令时开始',
            '2023-11-05' => '美国夏令时结束',
            '2023-03-26' => '欧洲夏令时开始',
            '2023-10-29' => '欧洲夏令时结束'
        ];

        foreach ($dates as $date => $description) {
            list($year, $month, $day) = explode('-', $date);

            // 获取GMT时间戳
            $gmtTimestamp = gmmktime(12, 0, 0, $month, $day, $year);

            $results[$description] = [
                'date' => $date,
                'gmt_timestamp' => $gmtTimestamp,
                'gmt_time' => gmdate('Y-m-d H:i:s', $gmtTimestamp),
                'ny_time' => date('Y-m-d H:i:s T', strtotime("$date 12:00:00 America/New_York")),
                'london_time' => date('Y-m-d H:i:s T', strtotime("$date 12:00:00 Europe/London"))
            ];
        }

        return $results;
    }
}

// 使用示例
echo "时区和夏令时处理示例\n\n";

// 1. 时区转换
echo "1. 时区转换对比:\n";
echo "   北京时间 2023-12-25 20:00:00 在不同时区的时间戳:\n\n";
$comparison = TimezoneConverter::compareTimezones(20, 0, 0, 12, 25, 2023);

foreach ($comparison as $desc => $data) {
    echo "   " . str_pad($desc, 25) . ": ";
    echo "时间戳=" . $data['timestamp'] . ", ";
    echo "GMT时间=" . $data['gmt_time'] . ", ";
    if (isset($data['offset'])) {
        echo "时区偏移=UTC" . ($data['offset'] >= 0 ? '+' : '') . $data['offset'];
    }
    echo "\n";
}

// 2. 夏令时演示
echo "\n2. 夏令时转换演示:\n";
$dstResults = TimezoneConverter::demonstrateDST();

foreach ($dstResults as $desc => $data) {
    echo "\n   " . $desc . " (" . $data['date'] . "):\n";
    echo "   GMT时间: " . $data['gmt_time'] . "\n";
    echo "   纽约时间: " . $data['ny_time'] . "\n";
    echo "   伦敦时间: " . $data['london_time'] . "\n";
}

// 3. gmmktime与时区设置的独立性
echo "\n3. gmmktime与时区设置的独立性:\n";
date_default_timezone_set('Asia/Shanghai');
echo "   当前时区设置: " . date_default_timezone_get() . "\n";

// gmmktime不受时区设置影响
$gmtTime1 = gmmktime(12, 0, 0, 1, 1, 2023);
echo "   gmmktime(12,0,0,1,1,2023): " . $gmtTime1 . " (" . gmdate('Y-m-d H:i:s', $gmtTime1) . " GMT)\n";

date_default_timezone_set('America/New_York');
echo "   更改时区为: " . date_default_timezone_get() . "\n";

// 同样的gmmktime调用,结果不变
$gmtTime2 = gmmktime(12, 0, 0, 1, 1, 2023);
echo "   gmmktime(12,0,0,1,1,2023): " . $gmtTime2 . " (" . gmdate('Y-m-d H:i:s', $gmtTime2) . " GMT)\n";
echo "   结果是否相同: " . ($gmtTime1 === $gmtTime2 ? '是' : '否') . " (应该相同)\n";

// mktime受时区设置影响
$localTime1 = mktime(12, 0, 0, 1, 1, 2023);
echo "   mktime(12,0,0,1,1,2023): " . $localTime1 . " (" . date('Y-m-d H:i:s', $localTime1) . ")\n";
?>
                            

输出:


时区和夏令时处理示例

1. 时区转换对比:
   北京时间 2023-12-25 20:00:00 在不同时区的时间戳:

   GMT                    : 时间戳=1703505600, GMT时间=2023-12-25 12:00:00, 时区偏移=UTC+0
   北京时间 (UTC+8)       : 时间戳=1703534400, GMT时间=2023-12-25 12:00:00, 时区偏移=UTC+8
   纽约时间 (UTC-5/UTC-4) : 时间戳=1703520000, GMT时间=2023-12-25 12:00:00, 时区偏移=UTC-5
   伦敦时间 (GMT/BST)     : 时间戳=1703505600, GMT时间=2023-12-25 12:00:00, 时区偏移=UTC+0
   悉尼时间 (UTC+10/UTC+11): 时间戳=1703541600, GMT时间=2023-12-25 12:00:00, 时区偏移=UTC+11

2. 夏令时转换演示:

   美国夏令时开始 (2023-03-12):
   GMT时间: 2023-03-12 12:00:00
   纽约时间: 2023-03-12 08:00:00 EDT
   伦敦时间: 2023-03-12 12:00:00 GMT

   美国夏令时结束 (2023-11-05):
   GMT时间: 2023-11-05 12:00:00
   纽约时间: 2023-11-05 07:00:00 EST
   伦敦时间: 2023-11-05 12:00:00 GMT

   欧洲夏令时开始 (2023-03-26):
   GMT时间: 2023-03-26 12:00:00
   纽约时间: 2023-03-26 08:00:00 EDT
   伦敦时间: 2023-03-26 13:00:00 BST

   欧洲夏令时结束 (2023-10-29):
   GMT时间: 2023-10-29 12:00:00
   纽约时间: 2023-10-29 08:00:00 EDT
   伦敦时间: 2023-10-29 12:00:00 GMT

3. gmmktime与时区设置的独立性:
   当前时区设置: Asia/Shanghai
   gmmktime(12,0,0,1,1,2023): 1672574400 (2023-01-01 12:00:00 GMT)
   更改时区为: America/New_York
   gmmktime(12,0,0,1,1,2023): 1672574400 (2023-01-01 12:00:00 GMT)
   结果是否相同: 是 (应该相同)
   mktime(12,0,0,1,1,2023): 1672596000 (2023-01-01 12:00:00)
                            
示例 3:实际应用 - 国际事件调度系统

<?php
/**
 * 国际事件调度系统
 */
class InternationalEventScheduler {

    /**
     * 创建GMT时间的事件
     */
    public static function createEvent($title, $gmtHour, $gmtMinute, $day, $month, $year): array {
        $timestamp = gmmktime($gmtHour, $gmtMinute, 0, $month, $day, $year);

        return [
            'title' => $title,
            'gmt_timestamp' => $timestamp,
            'gmt_time' => gmdate('Y-m-d H:i:s', $timestamp),
            'local_times' => self::getLocalTimes($timestamp)
        ];
    }

    /**
     * 获取事件在不同时区的本地时间
     */
    private static function getLocalTimes($gmtTimestamp): array {
        $timezones = [
            'Asia/Shanghai' => '上海',
            'America/New_York' => '纽约',
            'Europe/London' => '伦敦',
            'Asia/Tokyo' => '东京',
            'Australia/Sydney' => '悉尼',
            'Europe/Paris' => '巴黎'
        ];

        $localTimes = [];

        foreach ($timezones as $tz => $city) {
            $date = new DateTime('@' . $gmtTimestamp); // 从Unix时间戳创建(UTC)
            $date->setTimezone(new DateTimeZone($tz));
            $localTimes[$city] = [
                'time' => $date->format('Y-m-d H:i:s'),
                'timezone' => $tz,
                'offset' => $date->getOffset() / 3600
            ];
        }

        return $localTimes;
    }

    /**
     * 检查时间冲突(基于GMT时间)
     */
    public static function checkConflict($event1, $event2, $durationMinutes = 60): bool {
        $start1 = $event1['gmt_timestamp'];
        $start2 = $event2['gmt_timestamp'];
        $end1 = $start1 + ($durationMinutes * 60);
        $end2 = $start2 + ($durationMinutes * 60);

        return !($end1 <= $start2 || $start1 >= $end2);
    }

    /**
     * 生成事件提醒
     */
    public static function generateReminders($event, $reminderMinutes = [60, 30, 15]): array {
        $reminders = [];

        foreach ($reminderMinutes as $minutes) {
            $reminderTime = $event['gmt_timestamp'] - ($minutes * 60);
            $reminders[] = [
                'minutes_before' => $minutes,
                'gmt_timestamp' => $reminderTime,
                'gmt_time' => gmdate('Y-m-d H:i:s', $reminderTime)
            ];
        }

        return $reminders;
    }

    /**
     * 计算最佳会议时间
     */
    public static function findBestMeetingTime($participants): ?array {
        // 示例:找到所有参与者都方便的GMT时间
        // 这里简化处理,实际应用中会有更复杂的逻辑

        $testTimes = [];
        $today = gmmktime(0, 0, 0); // 今天GMT午夜

        // 测试今天9点到18点每个小时(GMT时间)
        for ($hour = 9; $hour <= 18; $hour++) {
            $testTime = $today + ($hour * 3600);
            $testTimes[] = $testTime;
        }

        // 检查每个测试时间是否适合所有参与者
        foreach ($testTimes as $testTime) {
            $allAvailable = true;

            foreach ($participants as $participant) {
                // 检查参与者的本地时间是否在合理范围内
                $localTime = new DateTime('@' . $testTime);
                $localTime->setTimezone(new DateTimeZone($participant['timezone']));
                $localHour = (int)$localTime->format('G');

                if ($localHour < 9 || $localHour > 17) {
                    $allAvailable = false;
                    break;
                }
            }

            if ($allAvailable) {
                return [
                    'gmt_timestamp' => $testTime,
                    'gmt_time' => gmdate('Y-m-d H:i:s', $testTime),
                    'local_times' => self::getLocalTimes($testTime)
                ];
            }
        }

        return null;
    }
}

// 使用示例
echo "国际事件调度系统演示\n\n";

// 1. 创建国际事件
echo "1. 创建国际事件:\n";
$events = [
    InternationalEventScheduler::createEvent('全球产品发布会', 14, 0, 25, 12, 2023),
    InternationalEventScheduler::createEvent('亚太区会议', 8, 0, 26, 12, 2023),
    InternationalEventScheduler::createEvent('欧美技术分享会', 20, 0, 27, 12, 2023)
];

foreach ($events as $event) {
    echo "   事件: " . $event['title'] . "\n";
    echo "   GMT时间: " . $event['gmt_time'] . "\n";
    echo "   各地时间:\n";

    foreach ($event['local_times'] as $city => $timeInfo) {
        echo "     " . str_pad($city, 8) . ": " . $timeInfo['time'] . " (UTC" .
            ($timeInfo['offset'] >= 0 ? '+' : '') . $timeInfo['offset'] . ")\n";
    }
    echo "\n";
}

// 2. 检查时间冲突
echo "2. 时间冲突检查:\n";
$conflict = InternationalEventScheduler::checkConflict($events[0], $events[1]);
echo "   事件1和事件2是否冲突: " . ($conflict ? '是' : '否') . "\n\n";

// 3. 生成事件提醒
echo "3. 事件提醒设置:\n";
$reminders = InternationalEventScheduler::generateReminders($events[0], [60, 30, 10]);
foreach ($reminders as $reminder) {
    echo "   提前" . $reminder['minutes_before'] . "分钟: " . $reminder['gmt_time'] . " GMT\n";
}
echo "\n";

// 4. 寻找最佳会议时间
echo "4. 寻找最佳会议时间:\n";
$participants = [
    ['name' => '张三', 'timezone' => 'Asia/Shanghai'],
    ['name' => 'John', 'timezone' => 'America/New_York'],
    ['name' => 'Emma', 'timezone' => 'Europe/London']
];

$bestTime = InternationalEventScheduler::findBestMeetingTime($participants);

if ($bestTime) {
    echo "   找到最佳会议时间: " . $bestTime['gmt_time'] . " GMT\n";
    echo "   各地时间:\n";
    foreach ($bestTime['local_times'] as $city => $timeInfo) {
        echo "     " . str_pad($city, 8) . ": " . $timeInfo['time'] . "\n";
    }
} else {
    echo "   未找到适合所有参与者的时间\n";
}

// 5. 计算时间差
echo "\n5. 计算时间差:\n";
$now = time();
$eventTime = $events[0]['gmt_timestamp'];
$timeDiff = $eventTime - $now;

if ($timeDiff > 0) {
    $days = floor($timeDiff / 86400);
    $hours = floor(($timeDiff % 86400) / 3600);
    $minutes = floor(($timeDiff % 3600) / 60);

    echo "   距离'" . $events[0]['title'] . "'还有: ";
    if ($days > 0) echo $days . "天 ";
    if ($hours > 0) echo $hours . "小时 ";
    if ($minutes > 0) echo $minutes . "分钟";
    echo "\n";
} else {
    echo "   事件已开始或已结束\n";
}
?>
                            

输出:


国际事件调度系统演示

1. 创建国际事件:
   事件: 全球产品发布会
   GMT时间: 2023-12-25 14:00:00
   各地时间:
     上海    : 2023-12-25 22:00:00 (UTC+8)
     纽约    : 2023-12-25 09:00:00 (UTC-5)
     伦敦    : 2023-12-25 14:00:00 (UTC+0)
     东京    : 2023-12-25 23:00:00 (UTC+9)
     悉尼    : 2023-12-26 01:00:00 (UTC+11)
     巴黎    : 2023-12-25 15:00:00 (UTC+1)

   事件: 亚太区会议
   GMT时间: 2023-12-26 08:00:00
   各地时间:
     上海    : 2023-12-26 16:00:00 (UTC+8)
     纽约    : 2023-12-26 03:00:00 (UTC-5)
     伦敦    : 2023-12-26 08:00:00 (UTC+0)
     东京    : 2023-12-26 17:00:00 (UTC+9)
     悉尼    : 2023-12-26 19:00:00 (UTC+11)
     巴黎    : 2023-12-26 09:00:00 (UTC+1)

   事件: 欧美技术分享会
   GMT时间: 2023-12-27 20:00:00
   各地时间:
     上海    : 2023-12-28 04:00:00 (UTC+8)
     纽约    : 2023-12-27 15:00:00 (UTC-5)
     伦敦    : 2023-12-27 20:00:00 (UTC+0)
     东京    : 2023-12-28 05:00:00 (UTC+9)
     悉尼    : 2023-12-28 07:00:00 (UTC+11)
     巴黎    : 2023-12-27 21:00:00 (UTC+1)

2. 时间冲突检查:
   事件1和事件2是否冲突: 否

3. 事件提醒设置:
   提前60分钟: 2023-12-25 13:00:00 GMT
   提前30分钟: 2023-12-25 13:30:00 GMT
   提前10分钟: 2023-12-25 13:50:00 GMT

4. 寻找最佳会议时间:
   找到最佳会议时间: 2023-12-25 09:00:00 GMT
   各地时间:
     上海    : 2023-12-25 17:00:00
     纽约    : 2023-12-25 04:00:00
     伦敦    : 2023-12-25 09:00:00

5. 计算时间差:
   距离'全球产品发布会'还有: 0天 0小时 0分钟
                            
gmmktime() 与 mktime() 对比
特性 gmmktime() mktime()
时区基准 GMT/UTC 时间 本地时间(受时区设置影响)
参数解释 参数解释为 GMT 时间 参数解释为本地时间
返回值 GMT 时间的 Unix 时间戳 本地时间的 Unix 时间戳
时区影响 不受 date_default_timezone_set() 影响 date_default_timezone_set() 影响
夏令时处理 不考虑夏令时 考虑夏令时(如果适用)
适用场景 国际应用、跨时区计算、数据库存储 本地化应用、用户界面、本地计算
重要:对于同一组参数,gmmktime()mktime() 返回的时间戳会相差本地时区与 GMT 的时差。

<?php
// 示例:显示时差如何影响结果
date_default_timezone_set('Asia/Shanghai');
$hour = 12;
$minute = 0;
$second = 0;
$month = 12;
$day = 25;
$year = 2023;

$gmtTimestamp = gmmktime($hour, $minute, $second, $month, $day, $year);
$localTimestamp = mktime($hour, $minute, $second, $month, $day, $year);

echo "参数: $hour:$minute:$second $month/$day/$year\n";
echo "gmmktime(): " . $gmtTimestamp . " (" . gmdate('Y-m-d H:i:s', $gmtTimestamp) . " GMT)\n";
echo "mktime(): " . $localTimestamp . " (" . date('Y-m-d H:i:s', $localTimestamp) . " 本地时间)\n";
echo "差异: " . ($localTimestamp - $gmtTimestamp) . " 秒\n";
?>
                            
常见错误和注意事项
1. 混淆gmmktime()和mktime()

<?php
// 错误:期望本地时间却用了gmmktime
date_default_timezone_set('Asia/Shanghai');
$expectedLocalTime = '2023-12-25 20:00:00';
$timestamp = gmmktime(20, 0, 0, 12, 25, 2023); // 这是GMT时间20:00

echo "期望的时间: " . $expectedLocalTime . "\n";
echo "gmmktime得到的时间戳: " . $timestamp . "\n";
echo "实际本地时间: " . date('Y-m-d H:i:s', $timestamp) . " (错误!)\n";
echo "实际GMT时间: " . gmdate('Y-m-d H:i:s', $timestamp) . "\n";

// 正确:根据需求选择函数
echo "\n正确方法:\n";
echo "如果需要本地时间20:00,使用mktime(): " .
    date('Y-m-d H:i:s', mktime(20, 0, 0, 12, 25, 2023)) . "\n";
echo "如果需要GMT时间20:00,使用gmmktime(): " .
    gmdate('Y-m-d H:i:s', gmmktime(20, 0, 0, 12, 25, 2023)) . "\n";
?>
                            
2. 忽略参数的范围检查

<?php
// gmmktime会自动处理超出范围的参数
echo "自动参数调整:\n";

// 日期超出范围
$timestamp1 = gmmktime(0, 0, 0, 13, 1, 2023); // 13月 -> 下一年1月
echo "gmmktime(0,0,0,13,1,2023): " . gmdate('Y-m-d H:i:s', $timestamp1) . "\n";

// 时间超出范围
$timestamp2 = gmmktime(25, 70, 90, 12, 25, 2023); // 25:70:90
echo "gmmktime(25,70,90,12,25,2023): " . gmdate('Y-m-d H:i:s', $timestamp2) . "\n";

// 负值参数
$timestamp3 = gmmktime(-1, -30, 0, 12, 25, 2023); // -1:-30
echo "gmmktime(-1,-30,0,12,25,2023): " . gmdate('Y-m-d H:i:s', $timestamp3) . "\n";

// 但要注意:年份处理有限制
if (PHP_INT_SIZE === 4) { // 32位系统
    echo "\n32位系统年份限制:\n";
    $timestamp4 = gmmktime(0, 0, 0, 1, 1, 1900);
    echo "gmmktime(0,0,0,1,1,1900): " . ($timestamp4 === false ? 'false' : $timestamp4) . "\n";
}
?>
                            
3. 误解时间戳的含义

<?php
// Unix时间戳始终是相对于GMT的
$timestamp = gmmktime(12, 0, 0, 12, 25, 2023);

echo "时间戳 " . $timestamp . " 表示:\n";
echo "1. GMT时间: " . gmdate('Y-m-d H:i:s', $timestamp) . "\n";
echo "2. 任意时区的本地时间:\n";

$timezones = ['Asia/Shanghai', 'America/New_York', 'Europe/London'];
foreach ($timezones as $tz) {
    $date = new DateTime('@' . $timestamp);
    $date->setTimezone(new DateTimeZone($tz));
    echo "   " . $tz . ": " . $date->format('Y-m-d H:i:s T') . "\n";
}

echo "\n重要:Unix时间戳本身没有时区概念,它表示自1970-01-01 00:00:00 GMT以来的秒数。\n";
echo "显示时间时需要指定时区,这就是为什么date()和gmdate()输出不同的原因。\n";
?>
                            

注意事项

  • 时区独立性:gmmktime() 始终将参数解释为 GMT 时间,不受 date_default_timezone_set() 影响。
  • 参数调整:函数会自动处理超出范围的参数(如 13 月会变为下一年 1 月)。
  • 夏令时:gmmktime() 不考虑夏令时,而 mktime() 会考虑。
  • 32位系统限制:在 32 位系统上,年份范围限制在 1901 到 2038 年之间。
  • 性能考虑:对于简单的当前时间戳,time() 函数更高效。
  • 时间戳本质:Unix 时间戳始终基于 GMT,无论使用哪个函数创建。
  • 向后兼容:在 PHP 8.0 之前,所有参数都是必需的。从 PHP 8.0 开始,参数可以为 null。
  • 错误处理:如果参数导致时间戳超出范围(如 32 位系统上的年份超出范围),函数返回 false

相关函数

mktime()

取得一个日期的 Unix 时间戳(本地时间)

time()

返回当前的 Unix 时间戳

strtotime()

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

gmdate()

格式化 GMT/UTC 日期和时间

date()

格式化本地时间/日期

DateTime::__construct()

面向对象的日期时间处理