一、PHP设置时区
在 PHP 中是通过日期和时间函数来获取日期和时间的。日期和时间函数依赖于服务器的时间设置,服务器的时间设置默认是格林尼治时间(零时区时间),如果不特意设置时间为特定时区时间,那么通过 PHP 有关函数获取到的时间为零时区的时间,比北京时间少 8 个小时。
在 PHP 中设置时区的方法有三种,下面来分别介绍一下。
1、在配置文件中设置
打开PHP 安装目录下的 php.ini 文件,在文件中搜索date.timezone,然后设置:
date.timezone = Asia/Shanghai
注意如果前面有;
需要去掉。
时区标识符可以通过访问https://www.php.net/manual/zh/timezones.php来查看
下面列举了一些常用的时区标识符及其含义:
- Asia/Shanghai —— 上海
- Asia/Chongqing —— 重庆
- Asia/Urumqi —— 乌鲁木齐
- Asia/Hong_Kong —— 香港
- Asia/Macao —— 澳门
- Asia/Taipei —— 台北
- Asia/Singapore —— 新加坡
- PRC —— 中国时区
设置完成后需要重启服务器
<?php
// 通过代码验证是否生效,与电脑时间一致说明成功
echo date('Y-m-d H:i:s',time());
?>
2、使用 ini_set() 函数设置时区
PHP 中的 ini_set() 函数可以设置指定配置选项的值,这个配置选项会在脚本运行时保持新的值,并在脚本结束时恢复。函数的语法格式如下:
ini_set($varname, $newvalue)
- $varname 为待修改的配置选项
- $newvalue 为配置选项的新值
<?php
ini_set('date.timezone', 'GMT');
echo '当前的格林尼治时间为:'.date('Y-m-d H:i:s',time()).'<br>';
ini_set('date.timezone', 'Asia/Urumqi');
echo '乌鲁木齐的当前时间为:'.date('Y-m-d H:i:s',time()).'<br>';
ini_set('date.timezone', 'Asia/Shanghai');
echo '上海的当前时间为:'.date('Y-m-d H:i:s',time());
?>
3、使用 date_default_timezone_set() 函数设置时区
PHP 中的 date_default_timezone_set() 函数可以为脚本中的所有时间日期函数设置一个默认时区,其语法格式如下:
date_default_timezone_set($timezone_identifier)
<?php
date_default_timezone_set('Asia/Urumqi');
echo '乌鲁木齐的当前时间为:'.date('Y-m-d H:i:s',time()).'<br>';
date_default_timezone_set('Europe/Lisbon');
echo '葡萄牙的当前时间为:'.date('Y-m-d H:i:s',time()).'<br>';
date_default_timezone_set('Asia/Shanghai');
echo '上海的当前时间为:'.date('Y-m-d H:i:s',time());
?>
二、PHP获取当前时间
在日期和时间函数中,UNIX 时间戳的获取非常重要,时间戳是一个字符序列,是指格林尼治时间 1970年 01 月 01 日 00 时 00 分 00 秒(北京时间 1970 年 01 月 01 日 08 时 00 分 00 秒)起至现在的总毫秒数。下面介绍几个获取当前时间的函数。
1、mktime()
int mktime ([ int $hour = date("H") [, int $minute = date("i") [, int $second = date("s") [, int $month = date("n") [, int $day = date("j") [, int $year = date("Y") [, int $is_dst = -1 ]]]]]]] )
该函数根据给出的参数返回 UNIX 时间戳。时间戳是一个长整数,包含了从 UNIX 纪元到给定时间的秒数。
<?php
echo mktime(); //没有设置参数, 则默认取得当前GMT时间
echo mktime(0,45,3,10,10,2021); //设置参数表示GMT时间2021年10月10日0点45分3秒
?>
2、microtime()
mixed microtime ([ bool $get_as_float ] )
- 返回当前 Unix 时间戳和微秒数
<?php
echo microtime(); //返回 msec sec 格式字符串表示时间
echo "<br/>";
echo microtime(true); //返回一个浮点型字符串表示时间
?>
3、time()
time()
- 返回当前的 UNIX 时间戳
<?php
echo time();
?>
4、strtotime()
int strtotime(string time [, int now])
- 可以将英文文本的日期时间描述直接解析为UNIX时间戳
<?php
echo @date("Y-m-d",strtotime("now"))."<br>"; //输出系统当前时间
echo @date("Y-m-d",strtotime("8 may 2019"))."<br>"; //输出2019-05-08
echo @date("Y-m-d",strtotime("+1 day"))."<br>"; //输出系统当前时间的后一天
echo @date("Y-m-d",strtotime("last monday"))."<br>"; //输出系统当前时间的星期一
?>
5、checkdate()
bool checkdate ( int $month , int $day , int $year )
- 检验日期和时间的有效性
<?php
var_dump( checkdate(7, 32, 2019) );
var_dump( checkdate(7, 9, 2019) );
?>
6、getdate()
getdate() 可取得日期时间信息。语法如下:
array getdate ([ int $timestamp = time() ] )
getdate() 函数返回关联数组键名
键名 | 说明 | 返回值例子 |
---|---|---|
seconds | 秒的数字表示 | 0 到 59 |
minutes | 分钟的数字表示 | 0 到 59 |
hours | 小时的数字表示 | 0 到 23 |
mday | 月份中第几天的数字表示 | 1 到 31 |
wday | 星期中第几天的数字表示 | 0(周日)到6(周六) |
mon | 月份的数字表示 | 1 到 12 |
year | 4 位数字表示的完整年份 | 比如:1999 或 2019 |
yday | 一年中第几天的数字表示 | 0 到 365 |
weekday | 星期几的完整文本表示 | Monday 到 Sunday |
month | 月份的完整文本表示 | January 到 December |
0 | 自从 UNIX 纪元开始至今的秒数,和 time() 的返回值以及用于 date() 的值类似 | 系统相关,典型值为 -2147483648 ~ 2147483647 |
<?php
echo "<pre>";
var_dump(getdate());
?>
三、时间日期格式化
当时间和日期保存在计算机中的时候,可以使用 UNIX 时间戳作为标准格式。但是 UNIX 时间戳的可读性很差,所以有时我们需要把 UNIX 时间戳格式化为可读性更好的时间和日期,或者格式化为其它软件需要的格式。 在 PHP 中可以使用 date() 函数来格式化一个本地的时间或日期,该函数的语法格式如下:
date($format [,$timestamp])
- $format:表示格式化后的时间格式,可以包含一些具有特殊含义的字符。
- $timestamp:表示待格式化的时间戳,是一个可选参数,默认为当前时间。也可以理解为 $timestamp 的默认值为 time()。
format 字符 | 说明 | 例子 |
---|---|---|
d | 月份中的第几天,使用两位的数字表示,不足两位时在前面补 0 | 01 到 31 |
D | 星期几的英文缩写(使用 3 个字母表示) | Mon 到 Sun |
l(“L”的小写字母) | 星期几的英文单词 | Sunday 到 Saturday |
N | 根据 ISO-8601 标准格式,使用数字表示星期中的第几天(PHP5.1.0 新加) | 1(表示星期一)到 7(表示星期天) |
S | 每月天数后面的英文后缀(使用 2 个字符表示) | st、nd、rd 或者 th。可以和 j 一起使用 |
w | 使用数字表示星期中的第几天 | 0(表示星期天)到 6(表示星期六) |
z | 使用数字表示一年中的第几天 | 0 到 365 |
W | 根据 ISO-8601 标准格式,使用数字表示年份中的第几周,每周从星期一开始,(PHP 4.1.0 新增) | 例如:42(当年的第 42 周) |
F | 月份的英文单词,例如 January 或者 June | January 到 December |
m | 使用两位的数字表示当前月份 | 01 到 12 |
M | 月份的英文缩写 | Jan 到 Dec |
n | 使用数字表示当前月份 | 1 到 12 |
t | 指定月份的天数 | 28 到 31 |
L | 指定的年份是否为闰年 | 如果是闰年值为 1,否则为 0 |
o | 根据 ISO-8601 标准格式使用数字表示年份,这和 Y 的作用相同(PHP 5.1.0 新增) | 1999 or 2019 |
Y | 使用 4 位数字表示完整的年份 | 例如:1999 或 2019 |
y | 使用 2 位数字表示年份 | 例如:99 或 03 |
a | 小写的上午和下午值 | am 或 pm |
A | 大写的上午和下午值 | AM 或 PM |
B | Swatch Internet 标准时 | 000 到 999 |
g | 使用 12 小时格式表示小时数 | 1 到 12 |
G | 使用 24 小时格式表示小时数 | 0 到 23 |
h | 使用 12 小时格式表示小时数,有前导零 | 01 到 12 |
H | 使用 24 小时格式表示小时数,有前导零 | 00 到 23 |
i | 使用两位数字表示分钟数,有前导零 | 00 到 59 |
s | 使用两位数字表示秒数,有前导零 | 00 到 59 |
u | 毫秒(PHP 5.2.2 新增)。需要注意的是 date() 函数总是返回 000000,因为它只接受 integer 参数,而 DateTime::format() 才支持毫秒 | 例如:654321 |
e | 时区标识 | 例如:UTC、GMT、Atlantic/Azores |
I(大写的“i”) | 是否为夏令时 | 夏令时为 1,否则为 0 |
O | 与格林尼治时间相差的小时数 | 例如:+0200 |
P | 与格林尼治时间(GMT)的差别,小时和分钟之间由冒号分隔 | 例如:+02:00 |
T | 本机所在的时区 | 例如:EST、MDT(在 windows 下为完整文本格式,例如“Eastern Standard Time”,中文版会显示“中国标准时间”) |
Z | 时差偏移量的秒数,UTC 西边的时区偏移量总是负的,UTC 东边的的时区偏移量总是正的 | -43200 到 43200 |
c | ISO-8601 格式的日期 | 2014-02-12T15:19:21+00:00 |
r | RFC 822 格式的日期 | 例如:Thu,21 Dec 2000 16:01:07 +0200 |
U | 从 UNIX 纪元(January 1 1970 00:00:00 GMT)开始至今的秒数 | 和 time() 返回相同的时间戳 |
<?php
echo date('Y-m-d H:i:s').'<br>';
$time = time();
echo '是一周中的第 '.date('w', $time).' 天<br>';
echo '今年是:';
date('L', $time)? print('闰年'):print('平年');
?>
四、综合案例
1、编写一个离毕业时间的倒记时
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="refresh" content="1">
<title>Document</title>
</head>
<body>
<?php
$now=@strtotime("now"); //获取系统当前时间
$endtime=@strtotime("2022-06-30 08:08:08"); //设定毕业时间,转为时间戳
$second=$endtime-$now; //获取毕业时间到现在时间的时间戳(秒)
$year=floor($second/3600/24/365); //从时间戳中换算出年数
$temp=$second-$year*365*24*3600; //从时间戳中去掉整年的秒数,剩下月的秒数
$month=floor($temp/3600/24/30); //算出月数
$temp=$temp-$month*30*24*3600;//从时间戳中去掉整月的秒数,剩下天的秒数
$day=floor($temp/3600/24); //算出天数
$temp=$temp-$day*24*3600; //从时间戳中去掉整天的秒数,剩下小时的秒数
$hour=floor($temp/3600); //算出小时数
$temp=$temp-$hour*3600; //从时间戳中去掉整小时的秒数,剩下分的秒数
$minute=floor($temp/60); //算出分数
$second=$temp-$minute*60; //最后就只有剩余的秒数了
echo "距离毕业还有{$year}年{$month}月{$day}天{$hour}小时{$minute}分{$second}秒。";
?>
</body>
</html>