日期和时间信息在 PHP 内部是以 64 位数字存储的, 它可以覆盖当前时间前后 2920 亿年的时间,这个范围之广,足以满足现有应用的实际需求。PHP提供了强大的日期时间处理功能,这里就举一些常见的函数。
一 时区设置
每个地区都有自己本地的时间,为了统一起见,我们把地球分为24个时区,每个时区都有自己的时间,PHP默认时UTC(UTC指协调世界时与GMT格林威治时间一致),而中国北京正好在时区的东八区,领先UTC8个小时,所以在计算我们当前时间的时候,要确认时区是否正确。
可以有两种方法去设置完成。可以通过修改php.ini中date.timezone属性完成。我们可以将这个属性的值改为Asia/Shang、PRC、Etc/GMT-8等中的一个,然后重启服务后,就可以在php中获取北京时间。另外可以通过在php脚本中使用date_timezone_set()函数设置时区,例如date_timezone_set('PRC')就表示中华人民共和国的时区。
二 获取Unix时间戳
【1】mktime —取得一个日期的 Unix 时间戳
根据给出的参数返回 Unix 时间戳。时间戳是一个长整数,包含了从 Unix 纪元,UTC/GMT的午夜(January 1 1970 00:00:00 )到给定时间的秒数。
-
该函数的所有参数都是可选的,参数可以从右向左省略,任何省略的参数会被设置成本地日期和时间的当前值。
-
如果给定的年份是两位数的,0~69表示2000-2069,70~100表示1970-2000
mktime ([ int $hour[, int $minute [, int $second [, int $month [, int $day [, int $year ]]]]]] ) : int
echo mktime(0,0,0,1,1,2019),'<br/>';//今年2019年1月1号0点0分0秒的时间戳
echo mktime(0,0,0,1,1,1970),'<br/>';//格林威治时间开始为0
echo mktime(0,0,0,1,1,1969),'<br/>';//时间低于1970年就会返回负数
echo mktime(0,0,0,1,1,19),'<br/>';//19表示的2019
echo mktime(0,0,0,1,1,70),'<br/>';//70表示的1970
- 任何给定月份的最后一天都可以被表示为下个月的第 "0" 天,而不是 -1 天。
//下面三行输出一样的结果1553990400都表示同一天
echo mktime(0, 0, 0, 3, 31, 2019),'<br/>';//表示2019年3月份最后一天
echo mktime(0, 0, 0, 4, 0, 2019),'<br/>';// 4月0号表示上个月最后一天
echo mktime(0, 0, 0, 5, -30, 2019),'<br/>';//5月-30表示上上个月最后一天
- 日期计算和验证方面很有用,它会自动计算超出范围的输入的正确值
//下面三行都表示2020年的1月1号00:00:00
echo mktime(0, 0, 0, 1, 1, 2020),'<br/>';//1577836800
echo mktime(0, 0, 0, 13, 1, 2019),'<br/>';
echo mktime(0, 0, 0, 12, 32, 2019),'<br/>';
echo mktime(24, 0, 0, 12, 31, 2019),'<br/>';
【2】strtotime()函数
将任何字符串的日期时间描述解析为 Unix 时间戳。本函数预期接受一个包含美国英语日期格式的字符串并尝试将其解析为 Unix 时间戳(自 January 1 1970 00:00:00 GMT 起的秒数),其值相对于 now 参数给出的时间,如果没有提供此参数则用系统当前时间。成功则返回时间戳,否则返回 FALSE。
strtotime ( string $time [, int $now = time() ] ) : int
echo strtotime("now"),'<br/>';//获取当前时间戳
echo strtotime("+1 day"),'<br/>';//当前时间+1天
echo strtotime("+1 week"),'<br/>';//当前时间+1周
echo strtotime("+1 week 2 days 4 hours 2 seconds"),'<br/>';//当前时间+1周2天四个小时2秒
echo strtotime("last Monday"),'<br/>';//上个周一的时间
- 计算距离毕业还有多少时间
//计算距离毕业还有多少时间
$now = strtotime("now");
$end = strtotime("2020-07-01 00:00:00");
$unix = $end - $now;
$year = floor($unix/3600/24/365);//年
$tmp = $unix - $year*365*24*3600;
$month= floor($tmp/3600/24/30);//月
$tmp = $tmp - $month*30*24*3600;
$day = floor($tmp/3600/24);//日
$tmp = $tmp - $day*3600*24;
$hour = floor($tmp/3600);//小时
$tmp = $tmp - $hour*3600;
$minute=floor($tmp/60);//分钟
$second= $tmp - $minute*60;//秒数
echo "END time {$year}year {$month}month {$day}day {$minute}minute {$second}second ";
【3】time()与microtime()函数
-
time —返回当前的 Unix 时间戳;返回自从 Unix 纪元(格林威治时间 1970 年 1 月 1 日 00:00:00)到当前时间的秒数。
-
microtime— 返回当前 Unix 时间戳和微秒数。php中大多数的时间格式都是以时间戳表示的,以s为单位,但是对于某些情况下不够精确,所以可以使用该函数精确到微秒。
time ( void ) : int //没有参数,返回当前时间戳
microtime ([ bool $get_as_float ] ) : mixed
//可选参数,如果不加参数默认返回格式'msec sec'的格式返回一个字符串,
//其中sec是秒数,mesc是微秒数,其单位是s;如果添加参数为true,则返回一个浮点数。
echo time(),'<br/>';//返回当前时间戳1553481852
echo $_SERVER['REQUEST_TIME'],'<br/>';//php5.1之后超全局数组中保存了获取请求时刻的时间戳
echo microtime(),'<br/>';//0.36221500 1553481852
echo microtime(true),'<br/>';//1553481852.3622
- 获取一个程序执行的时间
$time_start = microtime(true);
sleep(9);//休息9秒
$time_end = microtime(true);
echo $time_end-$time_start;//9.0002980232239
三 日期时间格式化
当日期时间需要保存或计算时后,使用unix时间戳作为标准格式,是挺好的,但是由于unix时间戳的格式可读性比较差,所以把时间戳格式化为可读性更好的日期与时间。
【1】调用getdate()函数获取日期和时间信息
返回一个根据 timestamp 得出的包含有日期信息的关联数组 array。如果没有给出时间戳则认为是当前本地时间,也就是说,其值默认为 time() 的返回值。
函数格式: getdate ([ int $timestamp = time() ] ) : array
例子:
var_dump(getdate());
/*
array (size=11)
'seconds' => int 38 #秒 数字表示0~59
'minutes' => int 35 #分 数字表示0~35
'hours' => int 5 #时 数字表示0~23
'mday' => int 25 #月份中第几天 数字表示1~31
'wday' => int 1 #星期中第几天 数字表示0(周日)~6(周六)
'mon' => int 3 #月份 数字表示1~12
'year' => int 2019 #年 数字表示
'yday' => int 83 #一年中的第几天数字表示0~365
'weekday' => string 'Monday' (length=6) #星期几的完整文本表示Sunday~Saturday
'month' => string 'March' (length=5) #月份的完整文本表示January~March
0 => int 1553488538 #时间戳 秒数
*/
【2】date()格式化日期/时间
函数有两个参数:第一个参数时必须的,规定时间戳的转化格式;第二个参数可选,提供一个时间戳,如果没有指定,默认为time()。返回将整数 timestamp 按照给定的格式字串而产生的字符串。
date ( string $format [, int $timestamp ] ) : string
其中,date()函数中第一个参数时通过特定字符组成的格式化字符串。如果在格式化字符串中字符前加上反斜线转义,那么可以避免按照格式化解释。下面看一下常见的格式化字符。 详情参考官网https://www.php.net/manual/zh/function.date.php
格式化字符 | 描述 | 示例 |
---|---|---|
Y | 4 位数字完整表示的年份 | 例如2019 |
m | 数字表示的月份,有前导零 | 01 到 12 |
d | 月份中的第几天,有前导零的 2 位数字 | 01 到 31 |
H | 小时,24 小时格式,有前导零 | 00 到 23 |
i | 有前导零的分钟数 | 00 到 59 |
s | 秒数,有前导零 | 00 到 59 |
y | 2 位数字表示的年份 | 例如19 |
M | 三个字母缩写表示的月份 | Jan 到 Dec |
D | 星期中的第几天,文本表示,3 个字母 | Mon 到 Sun |
h | 小时,12 小时格式,有前导零 | 01 到 12 |
g | 小时,12 小时格式,没有前导零 | 1 到 12 |
G | 小时,24 小时格式,没有前导零 | 0到 23 |
date_default_timezone_set('PRC');#设置中国时区
echo date('Y-m-d H:i:s'),'<br/>';//2019-03-25 13:22:58
echo date('l dS \of F Y h:i:s A'),'<br/>';//Monday 25th of March 2019 01:22:58 PM
四 日期运算比较
【1】对日期进行加减
$tomorrow = mktime(0,0,0,date('m'),date('d')+1,date('Y'));//对天数加1
$lastmonth = mktime(0,0,0,date('m')-1,date('d'),date('Y'));//对月份减一
//tomorrow 2019-03-26 00:00:00
echo date('\\t\o\m\o\r\r\o\w Y-m-d H:i:s',$tomorrow),'<br/>';
//last month is February
echo date('\l\a\s\t \m\o\n\t\h \i\s F',$lastmonth),'<br/>';
【2】比较两个日期大小
$a = strtotime('now');
$b = strtotime('2020-07-01');
echo $a<$b?'big':'small';
小结
- 设置时区用date_timezone_set()函数,PRC表示中国。
- mktime()设置日期时间戳;strtotime()将任何字符串时间描述解析为时间戳。
- time()获取当前时间戳;microtime()函数获取时间戳和微秒数。
- getdate()函数获取日期和时间信息;date()格式化日期/时间。