21.1.2 使用UNIX时间戳
date()函数的第二个参数是UNIX时间戳。我们对时间戳的意义做一个简单介绍。大多数UNIX系统保存当前日期和时间的方法是:保存格林威治标准时间从1970年1月1日零点起到当前时刻的秒数,以32位整列表示,其中1970年1月1日零点也叫UNIX纪元。如果对它不熟悉,这看起来有点深奥,但它是一个标准,而且整数适用于计算机处理。
UNIX时间戳是保存时间的一种紧凑简洁的方法,同时,它不会遭遇千年虫(Y2K)问题,该问题可以影响其他的紧凑或缩略的日期格式。然而,它们具有类似的问题,因为时间是通过一个32位的整数来表示的。如果软件需要处理1902年以前或2038年以后的事件,将会遇到一些问题。
在某些系统中(包括Windows),其范围更加有限。时间戳不能为负数,因此1970年以前的时间戳无法使用。要使代码具有可移植性,必须记住这一点。
我们不需要担心软件是否可以在2038年以后使用。时间戳没有固定的大小;它们是C语言的长整型,至少有32位。如果软件在2038年还会继续使用,那你的系统将肯定会使用了更大的类型。
虽然这是标准的UNIX惯例,但是即使在Windows服务器中运行PHP,这个格式仍然被date()函数和许多的PHP其他函数使用。唯一的不同就是,对于Windows来说,时间戳必须是正数。
如果要将一个日期和时间转变成UNIX时间戳,可以使用mktime()函数。该函数原型如下所示:
int mktime([int hour[,int minute[,int second[,int month[,
int day[,int year[,int is_dst]]]]]]])
除了最后一个参数is_dst外,其他参数的含义都很容易理解。参数is_dst表示该日期所示的时间是否是夏令时。如果是,可以将其设置为1,如果不是,设置为0(默认值),如果不知道,则设置为-1(默认值)。在使用-1的情况下,PHP将根据所运行的系统来确定它。该参数是可选的,很少用到。
使用该函数需要避免的一个主要陷阱是其参数顺序非常不直观。参数的顺序不允许漏掉一个时间参数。如果对具体时刻不在乎,可以将0传给hour、minute和second参数。
可以从参数列的右边开始遗漏参数的值。如果参数为空,将默认为当前时间。因此,如下所示的调用:
$timestamp=mktime();
将返回当前日期和时间的UNIX时间戳。当然,也可以通过如下所示的调用获取当前的UNIX时间戳:
$timestamp=time();
time()函数不需要任何参数,而且通常返回当前日期和时间的UNIX时间戳。
另一个选项就是date()函数,正如我们已经讨论的。格式字符串"U"要求一个时间戳。
如下语句等价于上两个语句:
$timestamp=date("U");
可以将用2位或4位数字表示的年份数传递给mktime()函数。从0~69的2位数字表示的年份可以解释成2000年到2069年,而从70~99的年份解释成1970年到1999年。
如下所示的代码是说明mktime()函数使用的其他例子:
$time=mktime(12,0,0);
该语句将给出今天日期的中午时间。
$time=mktime(0,0,0,1,1);
该语句将给出当前年的1月1日。请注意,在小时参数中,我们使用了0(而不是24)来表示午夜。
也可以在简单日期算法中使用mktime()函数。如下所示:
$time=mktime(12,0,0,$mon,$day+30,$year);
虽然($day+30)通常都会大于一个月的日期,该语句将在指定的日期基础上增加30天。
要消除冬令时和夏令时之间的问题,可以使用12点来代替0点。如果在25小时日中增加(246060)s,将停留在同一天。在中午时间增加相同的秒数,将给出11am时间,但是至少是在正确的一天。