8.2 PHP日期和时间函数
本节开始学习PHP的常用日期和时间函数的使用方法和技巧。
8.2.1 关于UNIX时间戳
在很多情况下,程序需要对日期进行比较、运算等操作。如果按照人们日常的计算方法,很容易知道6月5日和6月8日相差几天。然而,人们日常对日期的书写方式是2012-3-8或2012年3月8日星期五。这让程序如何运算呢?如果想知道3月8日和4月23日相差几天,则需要把月先转换为30天或31天,再对剩余天数加减。这是一个很麻烦的过程。
如果时间或者日期是一个连贯的整数,这样处理起来就很方便了。幸运的是,系统的时间正是以这种方式存储的,这种方式就是时间戳,也称为UNIX时间戳。UNIX系统和UNIX-like系统把当下的时间存储为32位的整数,这个整数的单位是秒,而这个整数的开始时间为格林尼治时间(GMT)的1970年1月1日的零点整。换句话说,现在的时间是GMT1970年1月1日的零点整到现在的秒数。
由于每一秒的时间都是确定的,这个整数就像一个章戳一样不可改变,所以就称为UNIX时间戳。
这个时间戳在Windows系统下也是成立的,但是与UNIX系统下不同的是,Windows系统下的时间戳只能为正整数不能为负值。所以想用时间戳表示1970年1月1日以前的时间是不行的。
PHP则是完全采用了UNIX时间戳的。所以不管PHP在哪个系统下运行都可以使用UNIX时间戳。
8.2.2 获取当前时间戳
获得当前时间的UNIX时间戳,以用于得到当前时间。完成此操作直接使用time()函数即可。time()函数不需要任何参数,直接返回当前日期和时间。
【例8.1】(实例文件:ch08\8.1.php)
<HTML> <HEAD> <TITLE>获取当前时间戳</TITLE> </HEAD> <BODY> <?php $t1 =time(); echo "当前时间戳为:".$t1; ?> </BODY> </HTML>
运行结果如图8-1所示。
【案例分析】
(1)图中的数字1344247868表示从1970年1月1日0点0分0秒到本程序执行时间隔的秒数。
(2)如果每隔一段时间刷新一次页面,获取的时间戳的值将会增加。这个数字会一直不断变大,即每过1秒,此值就会加1。
8.2.3 获取当前日期和时间
使用date()函数返回当前日期,如果在date()函数中使用参数“U”则返回当前时间的UNIX时间戳。如果使用参数“d”则直接返回当前月份的01到31的两位数日期。
然而,date()函数有很多的参数,具体含义如表8-1所示。
8.2.4 使用时间戳获取日期信息
如果相应的时间戳已经存储在数据库中,程序需要把时间戳转化为可读的日期和时间,才能满足应用的需要。PHP中提供了data()和getdate()等函数来实现从时间戳到通用时间的转换。
1.data()函数
data()函数主要是将一个UNIX时间戳转化为指定的时间/日期格式。该函数的格式如下。
srting data(string format [时间戳整数])
此函数将会返回一个字符串。该字符串就是一个指定格式的日期时间,其中format是一个字符串,用来指定输出的时间格式。时间戳整数可以为空,如果为空,则表示为当前时间的UNIX时间戳。
format参数是由指定的字符构成,具体字符的含义如表8-2所示。
format字符 | 含义 |
a | “am”或是“pm” |
A | “AM”或是“PM” |
d | 几日,两位数字,若不足两位则前面补零。例如:“01”至“31” |
D | 星期几,三个英文字母。例如:“Fri” |
F | 月份,英文全名。例如:“January” |
h | 12小时制的小时。例如:“01”至“12” |
H | 24小时制的小时。例如:“00”至“23” |
g | 12小时制的小时,不足两位不补零。例如:“1”至12” |
G | 24小时制的小时,不足两位不补零。例如:“0”至“23” |
i | 分钟。例如:“00”至“59” |
j | 几日,两位数字,若不足两位不补零。例如:“1”至“31” |
l | 星期几,英文全名。例如:“Friday” |
m | 月份,两位数字,若不足两位则在前面补零。例如:“01”至“12” |
n | 月份,两位数字,若不足两位则不补零。例如:“1”至“12” |
M | 月份,三个英文字母。例如:“Jan” |
s | 秒。例如:“00”至“59” |
S | 字尾加英文序数,两个英文字母。例如:“th”,“nd” |
t | 指定月份的天数。例如:“28”至“31” |
U | 总秒数 |
w | 数字型的星期几。例如:“0”(星期日)至“6”(星期六) |
Y | 年,四位数字。例如:“1999” |
y | 年,两位数字。例如:“99” |
z | 一年中的第几天。例如:“0”至“365” |
下面通过一个例子来理解format字符的使用方法。
【例8.2】(实例文件:ch08\8.2.php)
<HTML> <HEAD> <TITLE>获取当前时间戳</TITLE> </HEAD> <BODY> <?php date_default_timezone_set("PRC"); //定义一个当前时间的变量 $tt =time(); echo "目前的时间为:<br>"; //使用不同的格式化字符测试输出效果 echo date ("Y年m月d日[l]H点i分s秒",$tt)."<br>"; echo date ("y-m-d h:i:s a",$tt)."<br>"; echo date ("Y-M-D H:I:S A",$tt)."<br>"; echo date ("F,d,y l",$tt)." <br>"; echo date ("Y-M-D H:I:S",$tt)." <br>"; ?> </BODY> </HTML>
运行结果如图8-2所示。
【案例分析】
(1)date_default_timezone_set("PRC")语句的作用是设置默认时区为北京时间。如果不设置将会显示安全警告信息。
(2)格式化字符的使用方法非常灵活,只要设置字符串中包含的字符,date()函数就能将字符串替换成指定的时间日期信息。利用上面的函数可以随意输出自己需要的日期。
2.getdate()函数
getdate()函数可以获取详细的时间信息,函数的格式如下:
array getdate(时间戳整数)
getdate()函数返回一个数组,包含日期和时间的各个部分。如果它的参数时间戳整数为空,则表示直接获取当前时间戳。
下面举例说明此函数的使用方法和技巧。
【例8.3】(实例文件:ch08\8.3.php)
<HTML> <HEAD> <TITLE>获取当前时间戳</TITLE> </HEAD> <BODY> <?php date_default_timezone_set("PRC"); //定义一个时间的变量 $tm ="2012-08-08 08:08:08"; echo "时间为:". $tm. "<br>"; //将格式转化为UNIX时间戳 $tp =strtotime($tm); echo "此时间的UNIX时间戳为:".$tp. "<br>"; $ar1 =getdate($tp); echo "年为:". $ar1["year"]."<br>"; echo "月为:". $ar1["mon"]."<br>"; echo "日为:". $ar1["mday"]."<br>"; echo "点为:". $ar1["hours"]."<br>"; echo "分为:". $ar1["minutes"]."<br>"; echo "秒为:". $ar1["seconds"]."<br>"; ?> </BODY> </HTML>
运行结果如图8-3所示。
8.2.5 检验日期的有效性
使用用户输入的时间数据的时候,用户输入的数据不规范会导致程序运行出错。为了检查时间的合法有效性,需要使用checkdate()函数对输入日期进行检测。它的格式为:
checkdate(月份,日期,年份)
此函数检查的项目是,年份整数是否在0到32767之间,月份整数是否在1到12之间,日期整数是否在相应的月份的天数内。下面通过例子来讲述如何检查日期的有效性。
【例8.4】(实例文件:ch08\8.4.php)
<HTML> <HEAD> <TITLE>检查日期的有效性</TITLE> </HEAD> <BODY> <?php if(checkdate(2,31,2012)){ echo "这不可能。"; }else{ echo "2月没有31号。"; } ?> </BODY> </HTML>
运行结果如图8-4所示。
8.2.6 输出格式化时间戳的日期和时间
使用strftime()把时间戳格式化为日期和时间。它的格式如下:
strftime(格式,时间戳)
其中,格式决定了如何把其后面时间戳格式化并且输出;如果时间戳为空,则系统当前时间戳将会被使用。
日期和时间格式符如表8-3所示。
下面举例介绍如何输出格式化日期和时间。
【例8.5】(实例文件:ch08\8.5.php)
<HTML> <HEAD> <TITLE>输出格式化日期和时间</TITLE> </HEAD> <BODY> <?php date_default_timezone_set("PRC"); echo(strftime("%b %d %Y %X", mktime(20,0,0,12,31,98))); echo(gmstrftime("%b %d %Y %X", mktime(20,0,0,12,31,98))); //输出当前日期、时间和时区 echo(gmstrftime("It is %a on %b %d, %Y, %X time zone: %Z",time())); ?> </BODY> </HTML>
运行结果如图8-5所示。
8.2.7 显示本地化的日期和时间
由于世界上有不同的显示习惯和规范,所以日期和时间也会根据不同的地区显示为不同的形式。这就是日期时间显示的本地化。
实现此操作需要使用到setlocale()和strftime()两个函数。后者已经介绍过。
使用setlocale()函数来改变PHP的本地化默认值,实现本地化的设置。它的格式为:
setlocale(目录,本地化值)
(1)目录是指6个不同的本地化目录,如表8-4所示。
目录 | 说明 |
LC_ALL | 为后面其他的目录设定本地化规则的目录 |
LC_COLLATE | 字符串对比目录 |
LC_CTYPE | 字母划类和规则 |
LC_MONETARY | 货币表示规则 |
LC_NUMERIC | 数字表示规则 |
LC_TIME | 日期和时间表示规则 |
由于这里要对日期时间进行本地化设置,需要使用到的目录是LC_TIME。下面案例对日期时间本地化进行讲解。
(2)本地化值,是一个字符串,它有一个标准格式:language_COUNTRY.characterset。例如,如果想把本地化设为美国,按照此格式为en_US.utf8;如果想把本地化设为英国,按照此格式为en_GB.utf8;如果想把本地化设为中国,且为简体中文,按照此格式为zh_CN.gb2312,或者zh_CN.utf8。
【例8.6】(实例文件:ch08\8.6.php)
<HTML> <HEAD> <TITLE>显示本地化日期和时间</TITLE> </HEAD> <BODY> <?php date_default_timezone_set("PRC"); date_default_timezone_set("Asia/Hong_Kong"); setlocale(LC_TIME, "zh_CN.gb2312"); echo strftime("%z"); ?> </BODY> </HTML>
运行结果如图8-6所示。
【案例分析】
(1)date_default_timezone_set("Asia/Hong_Kong")设定时区为中国时区。
(2)setlocale()设置时间的本地化显示方式为简体中文方式。
(3)strftime("%z")返回所在时区,其在页面显示为简体中文方式。
8.2.8 将日期和时间解析为UNIX时间戳
使用给定的日期和时间,操作mktime()函数可以生成相应的UNIX时间戳。它的格式为:
mktime(小时,分钟,秒,月份,日期,年份)
在相应的时间和日期的部分输入相应位置的参数,即可得到相应的时间戳。下面的例子介绍此函数的应用方法和技巧。
【例8.7】(实例文件:ch08\8.7.php)
<HTML> <HEAD> <TITLE></TITLE> </HEAD> <BODY> <?php $timestamp = mktime(0,0,0,3,31,2012); echo $timestamp; ?> </BODY> </HTML>
运行结果如图8-7所示。
其中mktime(0,0,0,3,31,2012)使用的时间是2012年3月31日0点整。
8.2.9 日期时间在PHP和MySQL数据格式之间转换
日期和时间在MySQL中的存储是按照ISO8601格式存储的。这种格式要求以年份打头,如2012-03-08。从MySQL读取的默认格式也是这种格式。这种格式对于我们中国人是比较熟悉的。这样在中文应用中,几乎可以不用转换,就直接使用这种格式。
但是,在西方的表达方法中经常把年份放在月份和日期的后面,如March 08, 2012。所以,在接触到国际,特别是符合英语使用习惯的项目时,需要把ISO8601格式的日期时间进行合适的转换。
为了解决这个英文使用习惯和ISO8601格式冲突的问题,MySQL提供了把英文使用习惯的日期时间转换为符合ISO8601标准的两个函数,它们分别是DATE_FOMAT()和UNIX_TIMESTAMP()。这两个函数在SQL语言中使用。它们的具体用法将在介绍MySQL的部分详述。