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时间,但是至少是在正确的一天。