gmmktime是php中生成gmt/utc时间戳的函数,参数均视为gmt时间,$hour自php 8.0起必填,其余可空并默认为当前gmt值,返回整数时间戳,需校验是否为false。

gmmktime 是 PHP 中生成 GMT/UTC 时间戳的函数,它和 mktime 行为一致,但所有输入参数都被视为 GMT 时间(不经过本地时区转换)。直接用它构造 UTC 时间戳,比先用 mktime 再手动减去时区偏移更可靠、更少出错。
gmmktime 参数顺序和可选性要特别注意
它的签名是:gmmktime(int $hour, ?int $minute = null, ?int $second = null, ?int $month = null, ?int $day = null, ?int $year = null)。从 PHP 8.0 开始:
-
$hour不再可选,必须显式传入(哪怕你想用当前小时,也得写date('H')) - 其余参数(
$minute到$year)可以为null,此时会自动填充为当前 GMT 对应值 - 不能像老版本那样不传任何参数——那会抛出
ArgumentCountError - 月份是 1–12(不是 0–11),日期是 1–31,年份支持远超 2038(PHP 5+ 已无限制)
gmmktime 和 mktime 的关键区别在时区语义
看起来只是“多一个 g”,但行为差异直接影响结果:
-
mktime(0,0,0,1,1,2000)返回的是「本地时区下 2000 年 1 月 1 日 0 点」对应的 Unix 时间戳(比如东八区就是946656000) -
gmmktime(0,0,0,1,1,2000)返回的是「UTC 时间 2000 年 1 月 1 日 0 点」对应的 Unix 时间戳(固定为946684800) - 即使你把
date_default_timezone_set('UTC'),mktime和gmmktime的结果也一样——因为mktime总是把输入解释为本地时间,而gmmktime总是把输入解释为 GMT
常见错误:传了非法时间或忽略返回值校验
gmmktime 在遇到明显非法组合(如 2 月 30 日)时不会报错,而是自动归整(比如转成 3 月 2 日),这点和 mktime 一致。但它可能返回 false,尤其在极端年份(如远古或遥远未来)或平台整数溢出时:
- 务必检查返回值是否为
false,不要直接用于date()或数据库写入 - 避免传负数年份(如 -1000),某些系统会静默失败
- 不要依赖
is_dst参数——它在gmmktime中被完全忽略(文档明确说明 “doesn’t influence the result”) - 如果你需要验证某个 GMT 日期是否真实存在(比如考虑闰秒或历法变更),
gmmktime无能为力,得用DateTimeImmutable+setTimezone(new DateTimeZone('UTC'))配合异常捕获
替代方案:什么时候该换用 DateTime
对于复杂场景,gmmktime 显得笨重且难维护:
- 需要处理微秒、时区切换、相对日期(如 “UTC 下下周三”)?直接用
new DateTime('next Wednesday', new DateTimeZone('UTC')) - 要解析字符串(如
"2026-08-31T14:06:00Z")?DateTime::createFromFormat('c', $str)更安全 - 做跨时区计算(比如用户在东京下单,库存系统在伦敦)?
DateTime的setTimezone()可读性远高于手动加减秒数 -
gmmktime返回纯整数,丢失上下文;DateTime实例自带时区元数据,不易误用
真正容易被忽略的是:PHP 的 gmmktime 底层仍调用系统 mktime,并假设系统支持完整的 GMT 日历逻辑。在嵌入式或精简环境(如某些 Alpine 容器)中,gmmktime(25,0,0,1,1,2000) 可能意外返回 false 而非自动进位到第二天——这时没有警告,只有静默失败。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











