PHP笔记(二):实用日期函数

需求分析

近阶段常在捣腾PHP,之前大多数时候是借住于WORDPRESS、THINKPHP等折腾一些简单的应用或是弄个普通的企业网站玩玩;每次玩玩之后就不了了知了。

前两天看了兄弟连首席执行官李明先生,写给所有兄弟连学员们关于“学习这点事”的一篇帖子,深受感悟啊。

文中提到“程咬金三板斧学习秘笈”之一的“做好学习笔记”,对我触动很大;接触PHP也有一段时间了,可是所学零星知识大多数都已经忘却脑后,为了对自己有个交代,决定在博客中维护PHP笔记(在整理第一篇“如何利用正则匹配图片路径”的时候,居然还没这想法!!!)。

言归正转吧,这一节的主要需求:
1、记录PHP的几个基本日期函数 – 达到巩固和熟练掌握PHP中几个与日期有关的函数
2、整理几段PHP实用日期处理函数 – 日常事务处理中,难免会遇到各种与日期有关的处理需要,比如说要做个日历、统计个天数、随机取个日期、较验个日期是否合法等等。

知识回顾

与日期有关的PHP函数

date():格式化一个本地时间/日期

1、说明:

string date ( string $format [, int $timestamp ] )

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

注:时间戳是自 1970 年 1 月 1 日(00:00:00 GMT)以来的秒数。它也被称为 Unix 时间戳(Unix Timestamp)。
Unix时间戳(Unix timestamp),或称Unix时间(Unix time)、POSIX时间(POSIX time),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。Unix时间戳不仅被使用在Unix系统、类Unix系统中,也在许多其他操作系统中被广泛采用。

2、格式字串可以识别以下 format 参数的字符串

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
P 	与格林威治时间(GMT)的差别,小时和分钟之间有冒号分隔(PHP 5.1.3 新加) 	例如:+02:00
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()

格式字串中不能被识别的字符将原样显示。Z 格式在使用 gmdate() 时总是返回 0。

3、看看几个简单的例子:

// 假定今天是:March 10th, 2001, 5:16:18 pm
$today = date("F j, Y, g:i a");                 // March 10, 2001, 5:16 pm
$today = date("m.d.y");                         // 03.10.01
$today = date("j, n, Y");                       // 10, 3, 2001
$today = date("Ymd");                           // 20010310
$today = date('h-i-s, j-m-y, it is w Day z ');  // 05-16-17, 10-03-01, 1631 1618 6 Fripm01
$today = date('it is the jS day.');   // It is the 10th day.
$today = date("D M j G:i:s T Y");               // Sat Mar 10 15:16:08 MST 2001
$today = date('H:m:s m is month');     // 17:03:17 m is month
$today = date("H:i:s");                         // 17:16:17

time():返回当前的 Unix 时间戳

1、说明:

int time ( void )

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

2、示例:

$nextWeek = time() + (7 * 24 * 60 * 60);
                   // 7 days; 24 hours; 60 mins; 60secs
echo 'Now:       '. date('Y-m-d') ."n";
echo 'Next Week: '. date('Y-m-d', $nextWeek) ."n";

结果为:

Now: 2011-09-30
Next Week: 2011-10-07

strtotime():将任何英文文本的日期时间描述解析为 Unix 时间戳

1、说明:

int strtotime ( string $time [, int $now ] )

本函数预期接受一个包含美国英语日期格式的字符串并尝试将其解析为 Unix 时间戳(自 January 1 1970 00:00:00 GMT 起的秒数),其值相对于 now 参数给出的时间,如果没有提供此参数则用系统当前时间。

2、示例:

$example = array(
date("Y-m-d H:i:s",strtotime("now")),
date("Y-m-d H:i:s",strtotime("30 September 2011")),
date("Y-m-d H:i:s",strtotime("+1 day")),
date("Y-m-d H:i:s",strtotime("+1 week")),
date("Y-m-d H:i:s",strtotime("+1 week 2 days 4 hours 2 seconds")),
date("Y-m-d H:i:s",strtotime("next Thursday")),
date("Y-m-d H:i:s",strtotime("last Monday"))
);

print_r($example);

示例结果:

Array(
    [0] => 2011-09-30 05:22:46
    [1] => 2011-09-30 00:00:00
    [2] => 2011-10-01 05:22:46
    [3] => 2011-10-07 05:22:46
    [4] => 2011-10-09 09:22:48
    [5] => 2011-10-06 00:00:00
    [6] => 2011-09-26 00:00:00
)

mktime():取得一个日期的 Unix 时间戳

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)到给定时间的秒数。

参数可以从右向左省略,任何省略的参数会被设置成本地日期和时间的当前值。 

hour        小时数。
minute      分钟数。
second      秒数(一分钟之内)。
month       月份数。
day         天数。
year        年份数

2、示例:

function dates_range($date1, $date2)
{
   if ( $date1 < $date2 )
   {
       $dates_range[] = $date1;
       $date1 = strtotime( $date1 );
       $date2 = strtotime( $date2 );
       while ( $date1 != $date2 )
       {
           $date1 = mktime(0, 0, 0, date("m", $date1), date("d", $date1)+1, date("Y", $date1));
           $dates_range[] = date('Y-m-d', $date1);
       }
   }
   return $dates_range;
}

echo '<pre>';
print_r(dates_range('2009-12-25', '2010-01-05'));
echo '</pre>';

结果为:

Array(
    [0] => 2009-12-25
    [1] => 2009-12-26
    [2] => 2009-12-27
    [3] => 2009-12-28
    [4] => 2009-12-29
    [5] => 2009-12-30
    [6] => 2009-12-31
    [7] => 2010-01-01
    [8] => 2010-01-02
    [9] => 2010-01-03
    [10] => 2010-01-04
    [11] => 2010-01-05
)

getdate():取得日期/时间信息

1、说明:

array getdate ([ int $timestamp ] )

返回一个根据 timestamp 得出的包含有日期信息的结合数组。如果没有给出时间戳则认为是当前本地时间。

2、示例:

echo '<pre>';
print_r( getdate(time()) );
echo '</pre>';

结果为:

Array
(
    [seconds] => 8         //秒的数字表示                 0 到 59
    [minutes] => 42        //分钟的数字表示               0 到 59
    [hours] => 8           //小时的数字表示               0 到23
    [mday] => 30           //月份中第几天的数字表示        1到 31
    [wday] => 5            //星期中第几天的数字表示        0(表示星期天)到 6(表示星期六)
    [mon] => 9             //月份的数字表示                1 到 12
    [year] => 2011         //4 位数字表示的完整年份        例如:1999 或 2003
    [yday] => 272          //一年中第几天的数字表示        0 到 365
    [weekday] => Friday    //星期几的完整文本表示       Sunday 到 Saturday
    [month] => September   //月份的完整文本表示        January 到 December
    [0] => 1317372128      //自从 Unix 纪元开始至今的秒数,和 time() 的返回值以及用于 date() 的值类似。
)

以上只是简单地列出了几个常用函数,其中一些版本区别、注意事项、BUG处理等等更详细的说明信息,可移步cn.php.net查看在线手册。

实践操作

巩固了那么多知识后,来练练手吧,以下为部分实用代码片段。

如何获取此时此刻的时间戳?

$now = time(); 
//int(1317873281)

如何获取指定日期或时间的时间戳?

$appoint_time = strtotime('2011-06-24 11:58:18');
或者:
$appoint_time = mktime( 11, 58, 18, 6, 24, 2011); 
//int(1308916698)

计算自1999年06月24日至2011年10月01止,共计流逝了多少天?

//在PHP中,计算两个日期之间相隔的长度,最简单的方法就是通过计算两个UNIX时间戳之差来获得。
$start_time = mktime(0, 0, 0, 6, 24, 1999);
$endof_time = mktime(0, 0, 0, 10, 1, 2011);
$many_days = abs( ($endof_time - $start_time)/86400 );

结果为:

int(4482)

计算上例时间的年龄?

//floor — 舍去法取整
$age = floor( ($endof_time - $start_time)/(60*60*24*365) );

结果为:

float(12)

随机取某一时间段内的日期和时间?

$rand_time = rand( $start_time, $endof_time );
$rand_result = date( 'Y-m-d H:i:s', $rand_time );

结果为:

string(19) "2003-10-29 06:53:05"

获取指定月份应有的天数(28~31)

//假设指定月份为2008年4月
//获取的方法有很多,大概整理了几下几种
$total_days = date('t', mktime( 0, 0, 0, 4, 1, 2008 ) );
var_dump($total_days);

$last_days = date('d', mktime( 0, 0, 0, 5, 1, 2008 )-1 );
var_dump($last_days);

// cal_days_in_month: http://cn2.php.net/manual/zh/function.cal-days-in-month.php
$days_in_month = cal_days_in_month(1, 4, 2008);
var_dump( $days_in_month );

以上结果分别为:

string(2) "30"

string(2) "30"

int(30)

以上函数的基础知识,简单示例的演示,还需要静静消化;日常工作中少不了与这些知识打交道~~

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注