0%

PHP高级特性五之时间处理

综述

PHP中的时间处理函数是非常常用的,在这里我们介绍的主要内容有

UNIX时间戳

以整数表示格林威治标准时间,英文叫做 timestamp,例如 11230499325,它在UNIX系统中是以32位存储的。从协调世界时1970年1月1日0时0分0秒起至现在的总秒数,不考虑闰秒。 作用:方便我们计算使用(参于运算)。

获取时间函数

1.int time ( void )

返回自从 Unix 纪元(格林威治时间 1970 年 1 月 1 日 00:00:00)到当前时间的秒数,即返回的就是UNIX时间戳。

1
2
3
<?php 
echo time();
?>
1
 1426741342

2.array getdate ( [int timestamp] )/array getDate ( [int timestamp] )

可以通过传入时间戳获得时间,也可以不传参数获取时间。例如下面的例子获取了当前时间,返回类型是一个数组。

1
2
3
4
5
<?php 
echo "<pre>";
print_r(getDate()); //或者getdate();
echo "</pre>";
?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Array
(
[seconds] => 4
[minutes] => 6
[hours] => 5
[mday] => 19
[wday] => 4
[mon] => 3
[year] => 2015
[yday] => 77
[weekday] => Thursday
[month] => March
[0] => 1426741564
)

数组各个元素的说明如下

键名

说明

返回值例子

“seconds”

秒的数字表示

0 到 59

“minutes”

分钟的数字表示

0 到 59

“hours”

小时的数字表示

0 到 23

“mday”

月份中第几天的数字表示

1 到 31

“wday”

星期中第几天的数字表示

0(表示星期天)到 6(表示星期六)

“mon”

月份的数字表示

1 到 12

“year”

4 位数字表示的完整年份

例如:1999 或 2003

“yday”

一年中第几天的数字表示

0 到 365

“weekday”

星期几的完整文本表示

Sunday 到 Saturday

“month”

月份的完整文本表示

January> 到 December

可以传入时间戳参数,如下所示

1
2
3
4
5
6
<?php 
echo "<pre>";
print_r(getDate(time()+60*60*24));
print_r(getdate(time()));
echo "</pre>";
?>

时间戳转日期

1.string date ( string format [, int timestamp] )

返回将整数 timestamp 按照给定的格式字串而产生的字符串。如果没有给出时间戳则使用本地当前时间。换句话说,timestamp 是可选的,默认值为 time()。

1
2
3
4
5
<?php
echo date("Y-m-d H:i:s")."<br>";
echo date("Y-m-d H:i:s",time())."<br>";
echo date("Y-m-d H:i:s",time()+60*60*24)."<br>";
?>
1
2
3
2015-03-19 05:45:49
2015-03-19 05:45:49
2015-03-20 05:45:49

下面是格式化的字符表

format 字符

说明

返回值例子

-—

-—

d

月份中的第几天,有前导零的 2 位数字

01 到 31

D

星期中的第几天,文本表示,3 个字母

Mon 到 Sun

j

月份中的第几天,没有前导零

1 到 31

l(“L”的小写字母)

星期几,完整的文本格式

Sunday 到 Saturday

N

ISO-8601 格式数字表示的星期中的第几天(PHP 5.1.0 新加)

1(表示星期一)到 7(表示星期天)

S

每月天数后面的英文后缀,2 个字符

st,nd,rd 或者 th。可以和 j 一起用

w

星期中的第几天,数字表示

0(表示星期天)到 6(表示星期六)

z

年份中的第几天

0 到 366

星期

-—

-—

W

ISO-8601 格式年份中的第几周,每周从星期一开始(PHP 4.1.0 新加的)

例如:42(当年的第 42 周)

-—

-—

F

月份,完整的文本格式,例如 January 或者 March

January 到 December

m

数字表示的月份,有前导零

01 到 12

M

三个字母缩写表示的月份

Jan 到 Dec

n

数字表示的月份,没有前导零

1 到 12

t

给定月份所应有的天数

28 到 31

-—

-—

L

是否为闰年

如果是闰年为 1,否则为 0

o

ISO-8601 格式年份数字。这和 Y 的值相同,只除了如果 ISO 的星期数(W)属于前一年或下一年,则用那一年。(PHP 5.1.0 新加)

Examples: 1999 or 2003

Y

4 位数字完整表示的年份

例如:1999 或 2003

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>

时区

-—

-—

e

时区标识(PHP 5.1.0 新加)

例如:UTC,GMT,Atlantic/Azores

I

是否为夏令时

如果是夏令时为 1,否则为 0

O

与格林威治时间相差的小时数

例如:+0200

T

本机所在的时区

例如:EST,MDT(【译者注】在 Windows 下为完整文本格式,例如“Eastern Standard Time”,中文版会显示“中国标准时间”)。

Z

时差偏移量的秒数。UTC 西边的时区偏移量总是负的,UTC 东边的时区偏移量总是正的。

-43200 到 43200

完整的日期/时间

-—

-—

c

ISO 8601 格式的日期(PHP 5 新加)

2004-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()

日期转时间戳

1.int mktime ( [int hour [, int minute [, int second [, int month [, int day [, int year [, int is_dst]]]]]]] )

根据给出的参数返回 Unix 时间戳。时间戳是一个长整数,包含了从 Unix 纪元(January 1 1970 00:00:00 GMT)到给定时间的秒数。参数可以从右向左省略,任何省略的参数会被设置成本地日期和时间的当前值。 例如我们获取1997年12月1日的时间戳

1
2
3
<?php
echo mktime(0, 0, 0, 12, 1, 1997)."<br>";
?>
1
 880934400

在这里如果我们的年份如果填2位数,函数可以智能给我们转化,例如第六个参数填 97,那么则会识别为 1997年,如果填 03,那么则会识别为 2003年。那么有的小伙伴就问了,两个之间的分界点是哪一年哪一月哪一日呢?我们来看下面的例子

1
2
3
4
5
6
7
<?php
echo date("m-d-Y", mktime(0, 0, 0, 12, 32, 1997))."<br>";
echo date("M-d-Y", mktime(0, 0, 0, 3, 14, 98))."<br>";
echo date("M-d-Y", mktime(0, 0, 0, 1, 1, 03))."<br>";
echo date("M-d-Y", mktime(0, 0, 0, 1, 19, 38))."<br>";
echo date("M-d-Y", mktime(0, 0, 0, 1, 20, 38))."<br>";
?>
1
2
3
4
5
01-01-1998
Mar-14-1998
Jan-01-2003
Jan-19-2038
Jan-01-1970

在这里我们可以发现,当我们输入2038年的1月19日时,可以正常识别为2038-1-19,不过当我们输入2038年1月20日时,则识别成了1970-1-1,可见分界点就在2038-1-19这一天。 在这里有个有趣的2038年问题,扩展阅读一下

在计算机应用上,2038年问题可能会导致某些软件在2038年无法正常工作。所有使用UNIX时间表示时间的程序都将受其影响,因为它们以自1970年1月1日经过的秒数(忽略闰秒)来表示时间。这种时间表示法在类Unix(Unix-like)操作系统上是一个标准,并会影响以其C编程语言开发给其他大部份操作系统使用的软件。在大部份的32位操作系统上,此“time_t”数据模式使用一个有正负号的32位元整数(signedint32)存储计算的秒数。依照此“time_t”标准,在此格式能被表示的最后时间是2038年1月19日03:14:07,星期二(UTC)。超过此一瞬间,时间将会被掩盖(wrap around)且在内部被表示为一个负数,并造成程序无法工作,因为它们无法将此时间识别为2038年,而可能会依个别实作而跳回1970年或1901年。错误的计算及动作可能因此产生。

修改PHP默认时区

我们来看下面一个例子,是上面所说的调用date方法返回的时间。

1
2
3
<?php
echo date("Y-m-d H:i:s");
?>
1
2015-03-19 06:03:22

而现在我的电脑系统时间为

1
2015-03-19 14:03:22

这是什么原因?很简单,PHP程序中返回的是中时区的格林威治时间,而我们国家使用的是东八区区时,所以程序中的时间会慢8个小时。所以,我们只需要设置一下时区即可。

1.设置PHP.ini文件

这种方法是通用的设置方法,一次设置,其他所有编写的PHP文件都会生效,而且不需要在程序中设置了。只需要修改

1
2
3
4
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = PRC

默认的 date.timezone = UTC,在这里我们修改为中国的代号PRC即可。修改完之后记得重启服务器才能生效。 再运行程序,发现时间已经很准确了。

2.在程序中设置

1
2
3
4
5
<?php
date_default_timezone_set("PRC");
date_default_timezone_set("Asia/Shanghai");
date_default_timezone_set("Gtc/GET-8");
?>

上面三行语句均可使用,效果相同。第一个是设置中国时区,第二个是设置上海时区,第三个是设置东八区区时。 在此附亚洲区时

Asia/Aden

Asia/Almaty

Asia/Amman

Asia/Anadyr

Asia/Aqtau

Asia/Aqtobe

Asia/Ashgabat

Asia/Ashkhabad

Asia/Baghdad

Asia/Bahrain

Asia/Baku

Asia/Bangkok

Asia/Beirut

Asia/Bishkek

Asia/Brunei

Asia/Calcutta

Asia/Chita

Asia/Choibalsan

Asia/Chongqing

Asia/Chungking

Asia/Colombo

Asia/Dacca

Asia/Damascus

Asia/Dhaka

Asia/Dili

Asia/Dubai

Asia/Dushanbe

Asia/Gaza

Asia/Harbin

Asia/Hebron

Asia/Ho_Chi_Minh

Asia/Hong_Kong

Asia/Hovd

Asia/Irkutsk

Asia/Istanbul

Asia/Jakarta

Asia/Jayapura

Asia/Jerusalem

Asia/Kabul

Asia/Kamchatka

Asia/Karachi

Asia/Kashgar

Asia/Kathmandu

Asia/Katmandu

Asia/Khandyga

Asia/Kolkata

Asia/Krasnoyarsk

Asia/Kuala_Lumpur

Asia/Kuching

Asia/Kuwait

Asia/Macao

Asia/Macau

Asia/Magadan

Asia/Makassar

Asia/Manila

Asia/Muscat

Asia/Nicosia

Asia/Novokuznetsk

Asia/Novosibirsk

Asia/Omsk

Asia/Oral

Asia/Phnom_Penh

Asia/Pontianak

Asia/Pyongyang

Asia/Qatar

Asia/Qyzylorda

Asia/Rangoon

Asia/Riyadh

Asia/Saigon

Asia/Sakhalin

Asia/Samarkand

Asia/Seoul

Asia/Shanghai

Asia/Singapore

Asia/Srednekolymsk

Asia/Taipei

Asia/Tashkent

Asia/Tbilisi

Asia/Tehran

Asia/Tel_Aviv

Asia/Thimbu

Asia/Thimphu

Asia/Tokyo

Asia/Ujung_Pandang

Asia/Ulaanbaatar

Asia/Ulan_Bator

Asia/Urumqi

Asia/Ust-Nera

Asia/Vientiane

Asia/Vladivostok

Asia/Yakutsk

Asia/Yekaterinburg

Asia/Yerevan

微妙精确计算

1.mixed microtime ( [bool get_as_float] )

microtime() 当前 Unix 时间戳以及微秒数。本函数仅在支持 gettimeofday() 系统调用的操作系统下可用。 如果调用时不带可选参数,本函数以 “msec sec” 的格式返回一个字符串,其中 sec 是自 Unix 纪元(0:00:00 January 1, 1970 GMT)起到现在的秒数,msec 是微秒部分。字符串的两部分都是以秒为单位返回的。如果传入true参数,那么则会返回sec.msec的形式,是一个浮点数。 我们大多数用来计算程序执行时间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
class Timer {

private $startTime; //开始时间
private $stopTime; //结束时间
private $count = 0;

//初始化两个时间为0
function __construct(){
$this->startTime=0;
$this->stopTime=0;
}

//设置开始时间
function start(){
$this->startTime=microtime(true);
echo $this->startTime."<br>";
}

//设置结束时间
function stop(){
$this->stopTime=microtime(true);
echo $this->stopTime."<br>";
}

//计算过了多长时间
function spent(){
$this->start();
$this->dosomething();
$this->stop();
return ($this->stopTime - $this->startTime);
}

//程序执行某些任务
function dosomething(){
for($i=0; $i<10000; $i++)
{
$this->count ++;
}
}
}

$timer = new Timer();

echo $timer->spent();

?>
1
2
3
1426746064.4247
1426746064.4267
0.0019998550415039

可以发现,程序执行用了 1.99 微秒。 好,关于PHP中的时间问题,我们就介绍到这里,希望对大家有帮助。