PHP7语言基础——日期与时间

文章目录

  • 时区设置
    • 时区划分
    • 时区设置
  • PHP7日期和时间函数
    • 关于UNIX时间戳
    • 获取当前日期和时间
      • `time()`函数
      • `microtime()`函数
      • `getdate()`函数
  • 常用时间处理方法
    • 格式化时间显示
    • 计算两个日期间的时间差
    • 从字符串中解析日期和时间
    • 日期的加减运算
    • 输出格式化时间戳的日期和时间
    • 显示本地化的日期和时间
  • 验证日期
  • 日期和时间在PHP和MySQL数据格式之间的转换

日期和时间信息在PHP内部都是以64位数字存储的,它可以覆盖当前时间前后2920亿年的时间,这个范围之广,足以满足现有应用的实际需要。

时区设置

日期和时间函数依赖于服务器的时间设置,服务器的时间设置默认是格林威治时间(零时区时间)。如果不特意设置时间为特定时区时间,那么通过PHP有关函数获取到的时间为零时区的时间,比北京时间少8个小时。

时区划分

时区的划分是一个地理概念。从本初子午线开始向东和向西各有12个时区。北京时间是东八区,美国太平洋时间是西八区。

时区设置

时区设置方法主要有以下两种

  • 修改php.ini文件的设置。找到";date.timezone="选项,将其值修改为"date.timezone = Asia/Hong_kong",这样系统默认时间为东八区的时间。或者可以设置date.timezone=PRC,设置完成后,保存配置文件并重启服务器即可生效。
  • 在应用程序中使用函数date_default_timezone_set()函数,把时区设置为date_default_timezone_set("Asia/Hong_Kong")

PHP7日期和时间函数

关于UNIX时间戳

时间戳是一个字符序列,是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总毫秒数。

获取当前日期和时间

time()函数

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

time(void):int

【示例】


$t1 = time();   // 获取当前时间戳
echo "当前时间戳为:" . $t1;    // 输出当前时间戳
?>

程序输出结果:

当前时间戳为:1583334387

类似的函数还有gmmktime()mktime()

mktime([ int $hour = date("H")[, int $minute = date("i")[, int $second = date("s")[, int $month = date("n")[, int $day = date("j")[, int $year = date("Y")[, int $is_dst = -1]]]]]]] ) : int

根据给出的参数返回 Unix 时间戳,如果参数非法,本函数返回FALSE。时间戳是一个长整数,包含了从 Unix 纪元到给定时间的秒数。参数可以从右向左省略,任何省略的参数会被设置成本地日期和时间的当前值。

gmmktime()mktime()完全一样,只除了返回值是格林威治标准时的时间戳。

microtime()函数

该函数返回当前Unix时间戳以及微秒数。该函数仅在支持gettimeofday()系统调用的操作系统下可用。

microtime([bool $get_as_float]):mixed

如果调用时不带可选参数,本函数以"msec sec"格式返回一个字符串,其中sec是自Unix纪元起到现在的描述,msec是微秒部分。字符串的两部分都是以秒为单位返回的。如果给出了get_as_float参数并且其值等价于TRUE,将返回一个浮点数。

【示例】


// 不设置任何参数,则默认获得msce sec格式字符串
echo microtime();
echo "
"
; // 设置参数为true,返回一个浮点数 echo microtime(true); ?>

程序输出结果:

0.31818200 1583335900
1583335900.3182

getdate()函数

该函数返回一个根据timestamp得出的包含有日期信息的关联数组array。如果没有给出时间戳则认为是当前本地时间(此时和time()函数值相同)。

getdate([int $timestamp=time()]):array

【示例】


// 获取当前日期时间数组
$today = getdate();
echo "
";
var_dump($today);
?>

程序输出结果:

PHP7语言基础——日期与时间_第1张图片

getdate()函数返回关联数组键名含义:

键名 说明 返回值例子
seconds 秒的数字表示 0到59
minutes 分钟的数字表示 0到59
hours 小时的数字表示 0到23
mday 月份中第几天的数字表示 1到31
wday 星期中的第几天的数字表示 0(周日)到6(周六)
mon 月份的数字表示 1到12
year 4为数字表示的完整年份 如:1999或2020
yday 一年中第几天的数字表示 0到365
weekday 星期几的完成文本表示 Monday到Sunday
month 月份的完整文本表示 January到December
0 自从UNIX纪元开始至今的秒数,和time()的返回值以及用于date()的值类似 系统相关,典型值为-2147483648~2147483147

常用时间处理方法

格式化时间显示

可以使用date()函数对获取的时间进行格式化处理,语法如下:

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

返回将整数timestamp按照给定的格式字串而产生的字符串。如果没有给出时间戳则使用本地当前时间。

格式化字符串中可以识别的format参数如下表:

format字符 说明 返回值例子
d 月份中的第几天,有前导零的2位数字 01到31
D 星期中的第几天,文本表示,3个字母 Mon到Sun
月份中的第几天,没有前导零 1到31
l(L的小写字母) 星期几,完整的文本格式 Sunday到Saturday
N ISO-8601格式数字表示的星期中的第几天(PHP5.1.0新增) 1(表示星期一)到7(表示星期天)
S 每月天数后面的英文后缀,2个字符 st,nd,rd或者th。可以和j一起用
w(小写) 星期中的第几天,数字表示 0(表示星期天)到6(表示星期六)
z(小写) 年份中的第几天 0到365
星期
W(大写) ISO-8601格式年份中的第几周,每周从星期一开始(PHP4.1.0新增) 如:42(当年的第42周)
F 月份,完整的文本格式 January到December
m 数字表示的月份,有前导零 01到12
M 三个字母缩写小时的月份 Jan到Dec
n 数字表示的月份,没有前导零 1到12
t 指定的月份有几天 28到31
L 是否为闰年 如果是闰年为1,否则为0
o(小写) ISO-8601格式年分数字。这和Y的值相同,只除了如果ISO的星期数(W)属于前一年或下一年,则用那一年。(PHP5.10新增) 如:1999或2020
Y 4为数字完整表示的年份 如:1999或2020
y 2为数字表示的年份 如:99或20
时间
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>
u 毫秒(PHP5.2.2新增)。需要注意的是date()函数总是返回000000因为它只接受integer参数,而DateTime::format()才支持毫秒 如:654321
时区
e 时区标识(PHP5.1.0)新增 如:UTC,GMT,Atlantic/Azores
I(大写) 是否为夏令时 如果是夏令时为1,否则为0
O(大写) 与格林威治时间相差的小时数 如:+0200
P 与格林威治时间(GMT)的差别,小时和分钟之间有冒号分隔(PHP5.1.3新增) 如:+02:00
T 本机所在的时区 如:EST,MDT
Z 时差偏移量的秒数。UTC西边的时区偏移量总是负的,UTC东边的时区偏移量总是正的。 -43200到43200
完整的日期
c(小写) ISO 8601格式的日期(PHP5新增) 2004-02-12T15:19:21+00:00
r RFC 822格式的日期 如:Thu,21 Dec 2000 16:01:07+0200
U(大写) 从Unix纪元开始至今的秒数 同time()

如果格式字符串中有不能识别的字符将原样显示。

【示例】


// 设定要用的时区
date_default_timezone_set("PRC");
// 输出类似Monday
echo date("l");
echo "
"
; // 输出类似Thursday 05th of March 2020 01:03:57 AM echo date('l dS \of F Y h:i:s A'); echo "
"
; // 输出March 5, 2020 is on a Thursday echo "March 5, 2020 is on a ".date("l"); echo "
"
; /* 在格式参数中使用常量 */ //输出类似Thu, 05 Mar 2020 01:03:57 +0800 echo date(DATE_RFC2822); echo "
"
; // 输出类似2020-03-05T01:03:57+08:00 echo date(DATE_ATOM); echo "
"
; // 输出类似2020-03-05 01:03:57 echo date('Y-m-d H:i:s'); ?>

程序输出结果:

PHP7语言基础——日期与时间_第2张图片

计算两个日期间的时间差

计算日期的时间差需要先把两个日期转换成时间戳再计算。

【示例】


// 2020年1月1日19点30分0秒
$start = mktime(19, 30, 0, 1, 1, 2020);
// 2020年3月5日7点30分0秒
$end = mktime(7, 30, 0, 3, 5, 2020);
$diff_seconds = $end - $start;
// 一周的秒数是7*24*60*60=604800秒
$diff_weeks = floor($diff_seconds / 604800);
// 一天的秒数是24*60*60=86400秒
$diff_days = floor($diff_seconds / (24*60*60));
$diff_hours = floor($diff_seconds / (60*60));
$diff_minutes = floor($diff_seconds / 60);
echo "2020年1月1日19点30分0秒和2020年3月5日7点30分0秒之间相差$diff_seconds 秒,$diff_weeks 个星期,$diff_days 天,$diff_hours 小时,$diff_minutes 分钟";
?>

程序输出结果:

2020年1月1日19点30分0秒和2020年3月5日7点30分0秒之间相差5486400 秒,9 个星期,63 天,1524 小时,91440 分钟

从字符串中解析日期和时间

在PHP中可以使用strtotime()函数将任何英文文本的日期描述解析为UNIX时间戳,语法如下:

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

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

【示例】


echo strtotime("now"),"
"
; echo strtotime("10 September 2020"), "
"
; echo strtotime("+1 day"), "
"
; echo strtotime("+1 week"), "
"
; echo strtotime("+1 week 2 days 4 hours 2 seconds"), "
"
; echo strtotime("next Thursday"), "
"
; echo strtotime("last Monday"), "
"
; ?>

程序输出结果:

PHP7语言基础——日期与时间_第3张图片

日期的加减运算

可以使用strtotime()来计算一些日期时间间隔。

【示例】


$start = 'last Monday';
$interval = strtotime("$start + 4 days");
echo "现在\$interval 表示上周的". date("l", $interval);
?>

程序输出结果:

现在$interval 表示上周的Friday

如果日期使用时间戳表示,并且时间间隔也可以用秒来表示,就可以从时间戳中减去时间间隔。

【示例】


$start = time();
echo "现在是:" . date('Y-m-d', $start);
$interval = 7 * 24 * 3600;      // 一周
$end = $start - $interval;
echo "
"
; echo "上一周的今天是:" . date('Y-m-d', $end); ?>

程序输出结果:

现在是:2020-03-05
上一周的今天是:2020-02-27

输出格式化时间戳的日期和时间

可以使用strftime()把时间戳格式化为日期和时间,格式如下:

strftime( string $format[, int $timestamp = time()] ) : string

其中,$format决定了如何把其后面的时间戳格式化并输出。如果$timestamp为空,则使用系统当前时间戳。

format够识别的格式字串有以下标记:

格式 描述 返回值示例
%a 当前区域星期几的简写 Sun到Sat
%A 当前区域星期几的全称 Sunday到Saturday
%d 月份中的第几天,十进制数字 01到31
%e 月份中的第几天,十进制数字,一位的数字钱会加一个空格。 1到31
%j 年份中的第几天,带前导零的三位十进制数 001到366
%u 符合ISO-8601星期几的十进制数表达[1, 7],1表示星期一 1到7
%w 星期中的第几天,星期天为0 0到6
%U 本年的第几周,从第一周的第一个星期天作为第一天开始 1到13
%V 本年的第几周的ISO-8601:1988格式 01-53
%W 本年的第几周数,从个第一周的第一个星期一作为第一天开始 1-46
%b 当前区域月份的简写 Jan到Dec
%B 当前区域月份的全称 January到December
%h 当前区域月份的简写(%b的别名) Jan到Dec
%m 两位数的月份 01-12
%C 两位数显示世纪(年份除以100,截成整数) 19是20世纪
%g 2位数的年份,符合ISO-8601:1988星期数(参见%V)。和%V的格式和值一样,只除了如果ISO星期数属于前一年或后一年,则使用那一年。 如:2009年1月6日那一周是09。
%G %g的完整四位数版本 如:2009年1月3日那一周是2008。
%y 两位数显示年份 如:09是2009,79是1979
%Y 四位数显示年份 比如:2020
时间
%H 以24小时格式显示两位小时数 00到23
%I 以12小时格式显示两位小时数 01到12
%l(小写的’L’) 以12小时格式显示小时数,单个数字前含空格 1到12
%M 两位的分钟数 00到59
%p 执行时间的谢谢“AM”和“PM” 如:00:31是AM,22:23是PM
%P 指定时间的小写“am”或“pm” 如:00:31是am,22:23是pm
%r 和"%I:%M:%S %p"一样 如:21:34:17 是 09:34:17 PM
%R 和 “%H:%M” 一样 如: 12:35 AM 是 00:35,4:44 PM 是 16:44
%S 两位数字表示秒 00 到 59
%T 和 “%H:%M:%S” 一样 如: 09:34:17 PM 是 21:34:17
%X 前区域首选的时间表示法,不包括日期 如: 03:59:16 或 15:59:16
%z 从 UTC 的时区偏移 或 简写(由操作系统决定) 如: 东部时间是 -0500 或 EST
%Z %z 没有给出的 UTC 的时区偏移 或 简写(由操作系统决定) 如: -0500 或 EST 是东部时间
时间和日期戳
%c 当前区域首选的日期时间表达 如: 2009 年 2 月 5 日上午 12:45:10 是 Tue Feb 5 00:45:10 2009
%D 和 “%m/%d/%y” 一样 如: 2009 年 2 月 5 日是 02/05/09
%F 和"%Y-%m-%d"一样(常用于数据库时间戳) 如:2009 年 2 月 5 日是 2009-02-05
%s Unix纪元的时间戳(和 time() 函数一样) 如: 1979 年 9 月 10 日上午 8 点 40 分 00 秒是 305815200
%x 当前区域首选的时间表示法,不包括时间 如: 2009 年 2 月 5 日是 02/05/09
其他
%n 换行符("\n")
%t Tab 字符("\t")
%% 文字上的百分字符("%")

【示例】


// 设置时区
date_default_timezone_set("PRC");
// 打印格式化日期时间
echo(strftime("%b %d %Y %X", mktime(20,0,0,3,6,20)));
echo("
"
); // 打印格式化的格林威治日期时间 echo(gmstrftime("%b %d %Y %X", mktime(20,0,0,3,6,20))); echo("
"
); // 打印当前日期、时间和时区 echo(gmstrftime("it is %a on %b %d, %Y, %X time zone: %Z", time())); ?>

程序运行结果:

Mar 06 2020 20:00:00
Mar 06 2020 12:00:00
it is Thu on Mar 05, 2020, 17:47:13 time zone: 中国标准时间

注意:strftime和gmstrftime中的格式化字符串都不能有中文。

这个函数里%e修饰符不支持Windows。为了得到这个值可以用%#d修饰符代替。

%P修饰符不支持Mac OS X

显示本地化的日期和时间

使用setlocale()函数配合strftime()函数可以实现日期时间本地化。

setlocale()函数格式如下:

setlocale(int $category, string $local[, string $...]):string
setlocale(int $category, array $local):string

其中$local是一个字符串或数组,字符串值或数组元素值类似于:language_COUNTRY.chareacterset,如想把本地化设置为美国,按照此格式为en_US.utf8,如果想设为英国,值为en_GB.utf8,中国为zh_CN.gb2312或者zh_CN.utf8$category值是指7个不同的本地化目录,其值如下表所示。

目录 含义
LC_ALL 所有的设置
LC_COLLATE 字符串比较
LC_CTYPE 字符串的分类与转换
LC_MONETARY 货币表示规则
LC_NUMERIC 对于小数点的分隔
LC_TIME 时间与格式
LC_MESSAGES 系统响应 (如果PHP使用libintl编译)

【示例】


header("Content-Type: text/html;charset=gb2312");
// 设置时区为中国时区
date_default_timezone_set("Asia/Hong_Kong");
// 设置时间的本地化显示方式为中国
setlocale(LC_TIME, "zh_CN.gb2312");
// 输出所在的时区
echo strftime("%Z");

程序输出结果:

中国标准时间

验证日期

PHP提供了checkdate()函数来检验日期和时间的有效性,其格式如下:

checkdate(int $month, int $day, int $year):bool

该函数检查由参数构成的日期的合法性,如果每个参数都正确定义了则会被认为是有效的。

参数:


  • month:值是从1到12.
  • day:在给定的month所应该具有的天数范围内,闰年已经考虑进去了。
  • year:值是从1到32767

返回值:


如果给出的日期是有效的则返回TRUE,否则返回FALSE。

【示例】


var_dump(checkdate(1, 31, 2020));
var_dump(checkdate(2, 30, 2020));
?>

程序输出结果:

bool(true) bool(false)

日期和时间在PHP和MySQL数据格式之间的转换

日期和时间在MySQL中是按照ISO8601格式存储的。这种格式要求以年份打头,如2020-03-06。从MySQL读取的默认格式也是这种格式。国人会对这种格式比较熟悉,但是,西方的表达方法中经常把年份放在月份和日期的后面,如March 08, 2020。所以,在接触到国际,特别是符合英语使用习惯的项目时,需要把ISO8601格式的日期和时间加以核实的转换。

MySQL提供了把日期和时间转换为符合ISO8601标准的两个函数,DATE_FORMAT()UNIX_TIMESTAMP()

【MySQL示例】

// 获取当前时间
SELECT NOW();	// 2020/3/6 14:22:51
// 时间日期格式转换成时间戳格式
SELECT UNIX_TIMESTAMP(NOW());  // 1539238930
// 时间戳格式转换成时间日期格式
SELECT FROM_UNIXTIME(1539238971);
// 将当前时间转换为不同格式的字符串
SELECT DATE_FORMAT(NOW(),'%b %d %Y %h:%i %p')
SELECT DATE_FORMAT(NOW(),'%m-%d-%Y')
SELECT DATE_FORMAT(NOW(),'%d %b %y')
SELECT DATE_FORMAT(NOW(),'%d %b %Y %T:%f')

【PHP示例】

// 获取当前时间戳
time();
// 时间戳格式转换成时间日期格式
date('Y-m-d H:i:s', time());
// 时间日期格式转换成时间戳格式
strtotime('2020-03-05 14:24:06');

你可能感兴趣的:(PHP学习笔记)