時間戳:UNIX時間戳是保存日期和時間的一種緊湊簡潔的方法,是大多數UNIX系統中保存當前日期和時間的一種方法,也是在大多數計算機語言中表示日期和時間的一種標准格式。UNIX時間戳是從1970年1月1日0點(UTC/GMT的午夜)開始起到當前時間所經過的秒數
因為UNIX時間戳是一個32位的數字格式,所以特別適用於計算機處理,例如計算兩個時間點之間相差的天數。另外,由於文化和地區的差異,存在不同的時間格式,以及時區的問題。所以,UNIX時間戳也是根據一個時區進行標准化而設計的一種通用格式,並且這種格式可以很容易地轉換為任何格式
也因為UNIX時間戳是一個32位的整數表示的,所以在處理1902年以前或2038年以后的事件,將會遇到一些問題。另外,在Window下,由於時間戳不能為負數,如果使用PHP中提供的時間戳函數處理1970年之前的日期,就會發生錯誤。要使PHP代碼具有可移植性,必須牢記這一點
【strtotime()】
strtotime()預期接受一個包含美國英語日期格式的字符串並嘗試將其解析為Unix時間戳(自January 1 1970 00:00:00 GMT 起的秒數),其值相對於now參數給出的時間,如果沒有提供此參數則用系統當前時間
int strtotime ( string $time [, int $now = time() ] )
<?php
echo strtotime("now"), "\n";//1488259922
echo strtotime("10 September 2000"), "\n";// 968536800
echo strtotime("+1 day"), "\n";//1488346322
echo strtotime("+1 week"), "\n";//1488864722
echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n";//1489051924
echo strtotime("next Thursday"), "\n";//1488409200
echo strtotime("last Monday"), "\n";//1488150000
?>
<?php
$t ="1989-03-01 01:00:00";
echo strtotime($t);//604713600
date_default_timezone_set('PRC');
$t ="1989-03-01 01:00:00";
echo strtotime($t);//604688400
?>
【time()】
time()返回當前的 Unix 時間戳
int time ( void )
<?php
$nextWeek = time() + (7 * 24 * 60 * 60);// 7 days; 24 hours; 60 mins; 60 secs
echo 'Now: '. date('Y-m-d') ."\n";//Now: 2017-02-28
echo 'Next Week: '. date('Y-m-d', $nextWeek) ."\n";//Next Week: 2017-03-07
echo 'Next Week: '. date('Y-m-d', strtotime('+1 week')) ."\n";// Next Week: 2017-03-07
?>
【date()】
date()格式化一個本地時間/日期,返回將整數timestamp按照給定的格式字串而產生的字符串。如果沒有給出時間戳則使用本地當前時間。換句話說,timestamp是可選的,默認值為 time()
string date ( string $format [, int $timestamp ] )
format參數如下所示
日 d 月份中的第幾天,有前導零的 2 位數字 01 到 31 D 星期中的第幾天,文本表示,3 個字母 Mon 到 Sun j 月份中的第幾天,沒有前導零 1 到 31 l 星期幾,完整的文本格式 Sunday 到 Saturday N ISO-8601 格式數字表示的星期中的第幾天 1(表示星期一)到 7(表示星期天) S 每月天數后面的英文后綴,2 個字符 st,nd,rd 或者 th。可以和 j 一起用 w 星期中的第幾天,數字表示 0(表示星期天)到 6(表示星期六) z 年份中的第幾天 0 到 365 星期 W ISO-8601 格式年份中的第幾周,每周從星期一開始 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 格式年份數字 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 u 毫秒 654321 時區 e 時區標識(PHP 5.1.0 新加) UTC,GMT,Atlantic/Azores I 是否為夏令時 如果是夏令時為 1,否則為 0 O 與格林威治時間相差的小時數 +0200 P 小時和分鍾之間有冒號分隔 +02:00 T 本機所在的時區 EST,MDT Z 時差偏移量的秒數 -43200 到 43200 完整的日期/時間 c ISO 8601 格式的日期 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)開始至今的秒數
<?php
// 設定要用的默認時區。自 PHP 5.1 可用
date_default_timezone_set('UTC');
//Tuesday
echo date("l");
// Tuesday 28th of February 2017 05:41:19 AM
echo date('l dS \of F Y h:i:s A');
//July 1, 2000 is on a Saturday
echo "July 1, 2000 is on a " . date("l", mktime(0, 0, 0, 7, 1, 2000));
// Tue, 28 Feb 2017 05:41:19 +0000
echo date(DATE_RFC2822);
// 2000-07-01T00:00:00+00:00
echo date(DATE_ATOM, mktime(0, 0, 0, 7, 1, 2000));
?>
<?php
$t = time();
echo date("Y-m-d H:i:s")."<br>";//2017-02-28 06:56:42
echo date("Y/m/d H:i:s", $t)."<br>";//2017/02/28 06:56:42
echo date("Y年m月d日 H:i:s", $t)."<br>";//2017年02月28日 06:56:42
?>
【mktime()】
在PHP中,如果需要將日期和時間轉換為UNIX時間戳,可以調用mktime()函數
mktime()Unix時間戳,參數可以從右向左省略,任何省略的參數會被設置成本地日期和時間的當前值
int 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 ]]]]]]] )
<?php
// Prints something like: 2006-04-05T01:02:03+00:00
echo date('c', mktime(1, 2, 3, 4, 5, 2006));
?>
mktime()在做日期計算和驗證方面很有用,它會自動計算超出范圍的輸入的正確值
<?php
$t = mktime(1, 0, 0, 01, 03, 1989);
echo date('y-m-d H:i:s',$t) .'<br>';//89-01-03 01:00:00
$t = mktime(1, 0, 0, 01, 43, 1989);
echo date('y-m-d H:i:s',$t) .'<br>';//89-02-12 01:00:00
?>
時區
每個地區都有自己的本地時間,在網上及無級電通信中,時間的轉換問題顯得格外突出。整個地球分為24個時區,每個時區都有自己的本地時間。為了統一起見,使用一個統一的時間,稱為通用協調時(Universal Time Coordinated,UTC),是由世界時間標准設定的全球標准時間
PHP默認的時區設置是UTC時間,而北京位於時區的東8區,領先UTC8個小時,所以在使用time()等函數時,並不能得到正確的時間。可以通過以下兩種方式來修改時區
1、修改配置文件
如果使用的是獨立的服務器,有權限修改配置文件,設置時區就可以通過修改php.ini中的date.timezone屬性完成,可以將這個屬性的值設置為"Asia/Shang"、"Asia/Chongqing"、"Etc/GMT-8"或"PRC"中的一個
2、調用函數
可以通過調用函數date_default_timezone_set()函數來設置時區
date_default_timezone_set('PRC');
<?php
echo date("Y-m-d H:i:s")."<br>";//2017-02-28 07:06:05
date_default_timezone_set('PRC');
echo date("Y-m-d H:i:s")."<br>";//2017-02-28 14:06:05
?>
date_default_timezone_get()函數可以用來獲取當前的默認時區
<?php
echo date_default_timezone_get();//Europe/Paris
date_default_timezone_set('PRC');
echo date_default_timezone_get();//PRC
?>
微秒
在PHP中,大多數的時間格式都是以UNIX時間戳來表示的,而UNIX時間戳是心秒為最小的計量時間的單位。這對於某些應用程序來說不夠准確,所以可以調用microtime()返回當前UNIX時間戳和微秒數
mixed microtime ([ bool $get_as_float ] )
如果給出了 get_as_float 參數並且其值等價於 TRUE,microtime() 將返回一個浮點數
<?php
echo microtime() ."<br>";//0.72119500 1488282853
echo microtime(true) ;//1488282853.7212
?>
microtime()函數常用於性能分析
<?php
date_default_timezone_set("PRC");
$start = microtime(true);
for($i=0; $i<100000; $i++);
$end = microtime(true);
echo $end-$start;//0.0067892074584961
?>
獲取時間
前面介紹的date()函數用於設置時間,而getdate()函數則主要用於獲取時間
array getdate ([ int $timestamp = time() ] )
該函數將根據timestamp得出的包含有日期信息的關聯數組array。如果沒有給出時間戳則認為是當前本地時間
返回的關聯數組中的鍵名單元有以下幾個
鍵名 說明 返回值例子 "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 或 March January 到 December 0 自從 Unix 紀元開始至今的秒數,和 time() 的返回值以及用於 date() 的值類似
<?php
date_default_timezone_set('PRC');
//Array ( [seconds] => 8 [minutes] => 4 [hours] => 20 [mday] => 28 [wday] => 2 [mon] => 2 [year] => 2017 [yday] => 58 [weekday] => Tuesday [month] => February [0] => 1488283448 )
print_r(getdate())."<br>";
//Array ( [seconds] => 0 [minutes] => 0 [hours] => 0 [mday] => 1 [wday] => 6 [mon] => 1 [year] => 2000 [yday] => 0 [weekday] => Saturday [month] => January [0] => 946656000 )
print_r(getdate(strtotime('2000-1-1 0:0:0')));
?>
日歷
下面使用面向對象的寫法,完成一個簡單的日歷控件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
body{margin: 0;}
.active{color:white;background-color: blue;}
table{text-align:center;table-layout:fixed;border-collapse:collapse;width:400px;}
</style>
</head>
<body>
<?php
class Calendar{
private $year; //當前年
private $month; //當前月
private $start_weekday; //當前月的第一天對應的周幾
private $days; //當前月總天數
private $out; //用於構造日歷
//構造方法,用來初始化一些日期屬性
function __construct(){
//如果用戶沒有設置年份,則使用當前系統時間的年份
$this->year = isset($_GET['year']) ? $_GET['year'] : date('Y');
//如果用戶沒有設置月份,則使用當前系統時間的月份
$this->month = isset($_GET['month']) ? $_GET['month'] : date('m');
//利用date()函數的w參數獲取當前月第一天對應周幾
$this->start_weekday = date("w", mktime(0,0,0, $this->month, 1, $this->year));
//利用date()函數的t參數獲取當前月的天數
$this->days = date("t", mktime(0,0,0, $this->month, 1, $this->year));
}
//魔術方法,用於打印整個日歷
function __tostring(){
global $out;
$out .='<table>';//日歷以表格形式打印
$out .=$this->changeDate();//用戶自己設置日期
$out .=$this->weeksList();//打印周列表
$out .=$this->daysList();//打印日列表
$out .='</table>';//表格結束
return $out;
}
//輸出周列表
private function weeksList(){
global $out;
$week = array('日','一','二','三','四','五','六');
$out .= '<tr>';
for($i = 0; $i < count($week); $i++){
$out .= '<th>' .$week[$i] .'</th>';
}
$out.= '</tr>';
}
//輸出日列表
private function daysList(){
global $out;
$out .= '<tr>';
//輸出空格
for($j = 0; $j < $this->start_weekday; $j++){
$out .= '<td> </td>';
}
//輸出日期
for($k = 1; $k <= $this->days; $k++){
$j++;
if($k == date('d')){
$out .= '<td class="active">' .$k .'</td>';
}else{
$out .= '<td>'.$k .'</td>';
}
//換行
if($j % 7 == 0){
$out .= '</tr><tr>';
}
}
//補齊空格
while($j % 7 !== 0){
$out .= '<td> </td>';
$j++;
}
$out.= '</tr>';
}
//處理上一年數據
private function prevYear($year,$month){
$year = $year - 1;
if($year < 1970){
$year = 1970;
}
return "year={$year}&month={$month}";
}
//處理上一月數據
private function prevMonth($year,$month){
if($month == 1){
$year = $year - 1;
if($year < 1970){
$year = 1970;
}
$month = 12;
}else{
$month --;
}
return "year={$year}&month={$month}";
}
//處理下一年數據
private function nextYear($year,$month){
$year = $year + 1;
if($year > 2038){
$year = 2038;
}
return "year={$year}&month={$month}";
}
//處理下一月數據
private function nextMonth($year,$month){
if($month == 12){
$year = $year + 1;
if($year < 1970){
$year = 1970;
}
$month = 1;
}else{
$month ++;
}
return "year={$year}&month={$month}";
}
//改變日期
private function changeDate($url="1.php"){
global $out;
$out .='<tr>';
$out .='<td><a href="' .$url .'?' .$this->prevYear($this->year,$this->month) .'">' .'前一年' .'</a></td>';
$out .='<td><a href="' .$url .'?' .$this->prevMonth($this->year,$this->month) .'">' .'前一月' .'</a></td>';
$out .= '<td colspan="3">';
$out .='<form>';
$out .='<select name="year" onchange="window.location=\''.$url.'?year=\'+this.options[selectedIndex].value+\'&month='.$this->month.'\'">';
for($sy=1970;$sy<=2038;$sy++){
$selected = ($sy==$this->year) ? "selected" : "";
$out .='<option '.$selected .' value="' .$sy .'">' .$sy .'</option>';
};
$out .= '</select>';
$out .= '<select name="month" onchange="window.location=\''.$url.'?year='.$this->year.'&month=\'+this.options[selectedIndex].value">';
for($sm=1;$sm<=12;$sm++){
$selected1 = ($sm==$this->month) ? "selected" : "";
$out .='<option '.$selected1 .' value="' .$sm .'">' .$sm .'</option>';
}
$out .= '</select>';
$out .= '</form>';
$out .= '</td>';
$out .= '<td><a href="'.$url.'?'.$this->nextYear($this->year,$this->month).'">'.'后一年'.'</a></td>';
$out .= '<td><a href="'.$url.'?'.$this->nextMonth($this->year,$this->month).'">'.'后一月'.'</a></td>';
$out .= '</tr>';
}
}
echo new Calendar();
?>
</body>
</html>

