系統時差問題
調整方法有三:( 以台北時間+8為例 )
一、Linux時區的設定修改
# cd /etc/php/XXX(版本號)/apache2/ (備註1)
# vim php.ini
搜尋"date.timezone",將分號刪除。
備註1:
- 這是安裝apache套件,如果PHP是5.6之前的版本,位置是/etc/php5/apache2
- 如果是單獨安裝PHP,位置是
- 可執行下述指令,找到目前PHP的php.ini的位置:
> php -i|grep php.ini
二、撰寫程式時,在date()前面增加時區設定:
date_default_timezone_set(“時區");
例如:
<?php
date_default_timezone_set(“Asia/Taipei");
echo date(“Y-m-d H:i:s");
?>
時區列表:http://www.php.net/manual/en/timezones.php
三、撰寫程式時,date()直接加減時差:
date(“Y-m-d H:i:s",(time()+時差*3600))
例如:
<?php
echo date(“Y-m-d H:i:s",(time()+8*3600));
?>
參考資料:
http://www.domain.cn/blog/index.php/16064/action_viewspace_itemid_19492.html
date()的詳細介紹
下面為date()的詳細介紹(轉載:http://www.wanit.net/view.php?A_ID=30)
使用函式 date() 實現獲取系統當前時間
date(“Y-m-d H:i:s")
顯示的格式:西元年-月-日 小時:分鐘:秒
顯示結果範例:2019-03-05 17:05:02
可以自由設定顯示的內容、連接符號或是顯示位置,例如date(“m-d H")或者date(“dmY")等 。
時間參數
參數 | 說明 | 範例 |
Y | 年,四位元數字 | “1999″ |
y | 年,二位元數字 | “99″ |
m | 月份,若不足二位元則在前面補零 | “01″ 至 “12″ |
n | 月份 | “1″ 至 “12″ |
F | 月份,英文全名 | “January" |
M | 月份,三個英文字母 | “Jan" |
d | 幾日,若不足二位元則前面補零 | “01″ 至 “31″ |
j | 幾日,二位元數字 | “1″ 至 “31″ |
S | 字尾加英文序數,二個英文字母 | “th","nd" |
w | 星期幾,數字型 | “0″ (星期日) 至 “6″ (星期六) |
M | 星期幾,英文全名 | “Friday" |
D | 星期幾,三個英文字母 | “Fri" |
A | 上下午 | “AM" 或是 “PM" |
a | 上下午 | “am" 或是 “pm" |
h | 12 小時制的小時,若不足二位元則前面補零 | “01″ 至 “12″ |
g | 12 小時制的小時 | “1″ 至 12″ |
H | 24 小時制的小時,若不足二位元則前面補零 | “00″ 至 “23″ |
G | 24 小時制的小時 | “0″ 至 “23″ |
i | 分鐘 | “00″ 至 “59″ |
s | 秒 | “00″ 至 “59″ |
v | 毫秒(PHP 7.0.0以後) | “654″ |
u | 微秒,000000(PHP 5.2.2以後,DateTime::format()才支援) | “654321″ |
z | 一年中的第幾天 | “0″ 至 “365″ |
W | 一年中的第幾週 | “42″ |
t | 該月份的天數 | “28″ 至 “31″ |
U | 總秒數(1970-01-01 00:00:00開始計算) | 可參考time()函數 |
PHP中的日期處理
1. 得到目前的日期和時間
2. 改變日期顯示的方式
3. 轉換現在的日期為Unix的時間戳值
4. 改變日期a. 增加時間
b. 減去時間
c. 找出兩日期之間的間隔5. 為PHP添加DateAdd函數
6. 為PHP添加DateDiff函數
1.得到目前的日期和時間
在Unix中,時間的表示方式為計算從1970年1月1日零時起所過去的秒數,這稱為UNIX 時間戳(Unix Epoch)。
如果我們有這樣一段的代碼:
echo time();
將返回值
958905820
而此時的時間為2000年5月21日12時43分。
你也許會說這相當不錯。當這對我毫無幫助,或者只有一點幫助。在PHP中,對日期處理的函數都必須用到由time()返回的時間戳值。同時,由於PHP在Unix和Windows系統中均使用同樣的時間戳值,這就允許你不需要修改代碼即可在不同的系統間移植。另外的一個好處是time()函數返回的是一個整數,你可以將其作為整數欄位或文本欄位存入資料庫,而不必使用特別的日期/時間欄位。
你已經基本瞭解了Unix的時間戳值,現在讓我們來展示它的實際用途。
2.改變日期顯示的方式-日期和時間的顯示形式
PHP提供兩個辦法來將Unix的時間戳值轉換成為有用的資料。第一個是date()函數。這個函數有兩個參數-第一個字串用於設定你所希望返回的格式,第二個為Unix的時間戳值。
格式化字元串通過一些簡單的特殊格式化字元來顯示你所希望看到的格式的日期和時間。假設你希望日期以這樣的格式顯示“18h01 Sunday 21 May”。
我們需要對字串中的每一部分使用一個特殊格式化字元,你可以從PHP手冊中日期和時間函數庫中找到。這樣的特殊格式化字元數量不少,他們所表示的類似於星期幾、月的英文名、用2位或4位數表示的年份,是否是上午(AM)或下午(PM)以及其他。對於這個例子我們需要的特殊字元為:
‘H’ -24 小時制的小時
‘i’- 分鐘
‘l’- 星期幾的英文全名
‘d’- 本月的第幾日
‘F’- 月份的英文全名
因此我們的格式化字串為”Hhi l d F”, PHP代碼為:
echo date (“Hhi l d F" ,time());
當我們執行這段代碼,我們發現我們所得到的結果為:
180609 Sunday 21 May
這樣的結果看起來有些奇怪。讓我們再查一下PHP手冊,原來’h’所代表的是12 小時制的小時數。這再次證明了一句真理:“電腦只做你所告訴它該做的,而不是你想要它做的”。我們有兩個選擇。第一個是在h前使用轉義字元“”:
echo date (“Hhi l d F", time());
我們得到這樣的結果:
18h12 Sunday 21 May
這正是我們所要的。但如果我們在一個十分複雜的句子中需要包含日期和時間,我們是否需要對每個字元使用轉義字元?
答案當然是不。我們使用另一個函數strftime()。
strftime()有兩個好處。第一個好處我們並不在本文討論範圍內-如果你使用setlocale()函數,你可以通過strftime得到相應語言的月份的名稱。另外的一個好處是你可以將特別的日期和時間的格式化字元包含在你的字串中。這同時也意味著無論你是否要學習date()函數的所有特殊格式化字元,你都必須學習一整套完全不同的格式化字元。
strftime()工作的方式和date()沒有什麼不同,除了特殊格式化字元的前面必須添加一個百分號%。如果用strftime()函數,前面例子的代碼如下:
echo strftime (“%Hh%M %A %d %b" ,time());
結果為:
18h24 Sunday 21 May
這也許看起來將簡化繁,但考慮一下如果你所需要的顯示的為"Today is Sunday 21 May 2000. The time is somewhere close to 18h24." 我想使用date()函數無疑令人感到厭煩。
在開始的時候,我提及我們有兩種方式可以從Unix時間戳值中得到有用的資料。我們剛剛瞭解了date()和strftime()。另一個getdate()。這個函數只需要Unix 的時間戳值作為參數,而函數的返回值為日期和時間的陣列。
下面是一個例子:
$date_time_array = getdate (time());
echo $date_time_array[ “weekday"];
返回的結果為:
Sunday
除了"weekday",該陣列的其他部分為:
“seconds" –秒
“minutes" –分
“hours" –小時
“mday" – 本月的第幾天
“wday" -本周的第幾天(數字)
“mon" -月(數字)
“year" –年
“yday" – r本年的第幾天(數字)
“month" -月份全名
我們現在可以得到容易辨認的日期和時間。那麼其他呢?
3.轉換現在的日期為Unix的時間戳值
通常你必須處理一些日期或時間格式的資料。打開M$的一個Access資料庫,所有的日期都以YYYY/MM/DD的格式存儲,加入目前的日前即為2000/05/27。Mktime()函數可以將一個時間轉換成Unix的時間戳值。
函數的格式為:int mktime(int hour, int minute, int second, int month, int day, int year, int [is_dst] );
從左往右你必須提供小時、分、秒、月、天和年。最後一個參數用於指定你是否處於夏令時,此參數是可選的,所以我們將忽略它。
代碼如下:
echo mktime (0, 0,0 ,5, 27,2000 );
由於不知道小時、分和秒同時這些參數必須填寫,我將其設置為0。設置為0意味著時間為午夜。
$access_date = “2000/05/27″;
//explode()函數用一個字串作為分界來分解另一個字串。這個例子$access_date通過字串”/”來分解
$date_elements = explode(“/" ,$access_date);
// 此時
// $date_elements[0] = 2000
// $date_elements[1] = 5
// $date_elements[2] = 27
echo mktime (0, 0,0 ,$date_elements [1], $date_elements[ 2],$date_elements [0]);
我們看一個比從Access資料庫單純獲得日期更複雜的情況,我們得到一個以下格式的日期和時間:
2000/05/27 02:40:21 PM
4.修改日期
有時我們需要知道6小時以後是什麼時間,35天前的日期或者從你最後一次玩Quake3後已過去多少秒。我們已經知道如何用mktime()函數從單獨的 日期和時間中獲得Unix的時間戳記值。如果我們需要的並非目前日期和時間的Unix時間戳記值,我們該咋辦?下面是一些練習可以幫助說明我們後面所要做的。
正如前面所見,mktime()使用以下參數:小時、分、秒、月、天和年。想想第二節,getdate()函數可以為我們獲得這些參數。
//將目前的時間戳記值放入一陣列內
$timestamp = time();
echo $timestamp."
“;
$date_time_array = getdate( $timestamp);//用mktime()函數重新產生Unix時間戳記值
$timestamp = mktime($date_time_array [“hours"], $date_time_array[“minutes" ],$date_time_array[ “seconds"],$date_time_array [“mon"], $date_time_array[“mday" ],$date_time_array[ “year"]);
echo $timestamp;
看起來有一些令人感到迷惑。我將用一些變數來使上面的程式看起來更容易瞭解。
//將目前的時間戳記值放入一陣列內
$timestamp = time();
echo $timestamp."
“;
$date_time_array = getdate( $timestamp);$hours = $date_time_array[ “hours"];
$minutes = $date_time_array[“minutes"];
$seconds = $date_time_array[ “seconds"];
$month = $date_time_array[“mon"];
$day = $date_time_array[“mday"];
$year = $date_time_array[“year"];//用mktime()函數重新產生Unix時間戳記值
$timestamp = mktime($hours ,$minutes, $seconds,$month ,$day,$year);
echo $timestamp;
現在我們將由getdate()所產生的時間戳記值放入相對應的名稱變數中,所以代碼變得相對容易閱讀和理解。現在如果我們需要在目前的時間上加上19個小 時,我們用$hours+19代替mktime()函數中的$hours。mktime()將自動為我們將時間轉到第二天。
//將目前的時間戳記值放入一陣列內
$timestamp = time();
echo strftime( “%Hh%M %A %d %b",$timestamp)."
“;
$date_time_array = getdate($timestamp);
$hours = $date_time_array[“hours"];
$minutes = $date_time_array[“minutes"];
$seconds = $date_time_array[“seconds"];
$month = $date_time_array[“mon"];
$day = $date_time_array[“mday"];
$year = $date_time_array[“year"];//用mktime()函數重新產生Unix時間戳記值
//增加19小時
$timestamp = mktime($hours + 19, $minutes,$seconds ,$month, $day,$year);
echo strftime( “%Hh%M %A %d %b",$timestamp);
echo “
~E after adding 19 hours";
執行結果如下:
14h58 Saturday 03 Jun
09h58 Sunday 04 Jun
~E after adding 19 hours
減少時間也是同樣的-你只需要減少相應變數的值即可。
得到兩個不同時間值的差同樣也是非常簡單。你所需要做的只是將兩個時間值轉換為Unix的時間戳記值,然後兩者相減即可。兩者之差即為兩個時間所相隔的秒數。另外一些演算法可以很快地將秒轉為天、小時、分和秒。
5.為PHP添加DateAdd函數
正如在文章一開始我所說的-寫本文的原因是因為我在PHP中找不到類似ASP的DateDiff函數。在介紹完PHP是如何處理日期和時間,讓我們將ASP中常用的兩個函數移植到PHP。第一個函數是DateAdd。
根據Vbscript的文檔,DateAdd(interval,number,date)函數的定義為“返回已添加指定時間間隔的日期。”
Inetrval為表示要添加的時間間隔字串運算式,例如分或天;number為表示要添加的時間間隔的個數的數值運算式;Date表示日期。
Interval(時間間隔字串運算式)可以是以下任意值:
yyyy year年
q Quarter季度
m Month月
y Day of year一年的數
d Day天
w Weekday一周的天數
ww Week of year周
h Hour小時
n Minute分
s Second秒
w、y和d的作用是完全一樣的,即在目前的日期上加一天,q加3個月,ww加7天。
function DateAdd ($interval, $number, $date) {
$date_time_array = getdate($date);
$hours = $date_time_array[“hours"];
$minutes = $date_time_array[“minutes"];
$seconds = $date_time_array[“seconds"];
$month = $date_time_array[“mon"];
$day = $date_time_array[“mday"];
$year = $date_time_array[“year"];
switch ($interval) {case “yyyy":
$year +=$number; break;
case “q":
$month +=($number*3); break;
case “m":
$month +=$number; break;
case “y":
case “d":
case “w":
$day+=$number; break;
case “ww":
$day+=($number*7); break;
case “h":
$hours+=$number; break;
case “n":
$minutes+=$number; break;
case “s":
$seconds+=$number; break;}
$timestamp = mktime($hours ,$minutes, $seconds,$month ,$day, $year);
return $timestamp;}
我們可以將上面的原始碼儲存為dateadd.inc檔,然後執行以下原始碼:
include(‘dateadd.inc’);
$temptime = time();
echo strftime( “%Hh%M %A %d %b",$temptime);
$temptime = DateAdd(“n" ,50,$temptime);
echo “p";
echo strftime( “%Hh%M %A %d %b",$temptime);
執行結果如下:
15h41 Saturday 03 Jun
16h31 Saturday 03 Jun
6.為PHP添加DateDiff函數
現在DateAdd已經完成,那麼DateDiff呢?
根據文檔,DateDiff(interval,date1,date2)函數的定義為“返回兩個日期之間的時間間隔”。
Intervals參數的用法與DateAdd函數中的相同。出於避免過於複雜的考慮,我們決定忽略Vbscript中DateDiff函數中其它複雜的 參數,即其兩個可選的參數變數[firstdayofweek[, firstweekofyear]](它們用於決定星期中第一天是星期天還是星期一和一年中第一周的常數。而且我們只允許intervals有以下五個 值:"w"(周)、"d"(天)、"h"(小時)、"n"(分鐘) 和"s"(秒)。
下面的代碼是我們所需要的:
Function DateDiff ($interval, $date1,$date2) {
// 得到兩日期之間間隔的秒數
$timedifference = $date2 – $date1;
switch ($interval) {case “w": $retval = bcdiv($timedifference ,604800); break;
case “d": $retval = bcdiv( $timedifference,86400); break;
case “h": $retval = bcdiv ($timedifference,3600); break;
case “n": $retval = bcdiv( $timedifference,60); break;
case “s": $retval = $timedifference; break;}
return $retval;}
將上面的代碼存為datediff.inc檔,然後運行下面的代碼:
include(‘datediff.inc’);
include(‘dateadd.inc’);
$currenttime = time();
echo “Current time: “. strftime(“%Hh%M %A %d %b" ,$currenttime)."br";
$newtime = DateAdd (“n",50 ,$currenttime);
echo “Time plus 50 minutes: “. strftime(“%Hh%M %A %d %b" ,$newtime)."br";
$temptime = DateDiff (“n",$currenttime ,$newtime);
echo “Interval between two times: “.$temptime;
如果一切順利,你可以看到以下結果:
Current time: 16h23 Saturday 03 Jun
Time plus 50 minutes: 17h13 Saturday 03 Jun
Interval between two times: 50
範例說明
範例:日期比較
<?php
$Date_1="2007-07-12″;
$Date_2="2007-06-27″;
// 首先用explode這個函數來拆分字串:explode(“字串的切割部位",要被處理的字串)
$Date_explode_1=explode(“-“,$Date_1);
$Date_explode_2=explode(“-“,$Date_2);
// 拆分後的字串透過mktime函數來計算時間(其值以"秒"為單位)
$Day_1=mktime(0,0,0,$Date_explode_1[1],$Date_explode_1[2],$Date_explode_1[0]);
$Day_2=mktime(0,0,0,$Date_explode_2[1],$Date_explode_2[2],$Date_explode_2[0]);
$Days=round(($Day_1-$Day_2)/3600/24);
echo “$Date_1 和 $Date_2 間隔 $Days 天";
?>
範例:取得90天以後的日期
<?php
//$m為月,$d為天,$Y為年
$Y=date(Y);
$m=date(m);
$d=date(d);
//"Y年m月d日"為顯示的格式,可以改成"Y-m-d";mktime裡的"+"號表示多少天後的日期,反之,"-“號可以得到多少天前的日期
$out_date1=date( “Y年m月d日", mktime(0,0,0,$m,$d+7,$Y) ); //一週後
$out_date2=date( “Y年m月d日", mktime(0,0,0,$m,$d+14,$Y) ); //二週後
$out_date3=date( “Y年m月d日", mktime(0,0,0,$m+1,$d,$Y) ); //一個月後
$out_date4=date( “Y年m月d日", mktime(0,0,0,$m+2,$d,$Y) ); //二個月後
$out_date5=date( “Y年m月d日", mktime(0,0,0,$m+3,$d,$Y) ); //三個月後
$out_date6=date( “Y年m月d日", mktime(0,0,0,$m+6,$d,$Y) ); //六個月後
$out_date7=date( “Y年m月d日", mktime(0,0,0,$m,$d,$Y+1) ); //一年後
echo date(“Ymd", time() + 90*86400);
echo date(“Y-m-d",strtotime(“2004-10-26 +90day"));
echo date(“Y-m-d",strtotime(“+90 day"));
?>
PS:抱歉,這是以前找到的文章,不太適合,之後會慢慢修改
date_default_timezone_set(“Asia/Taipei");
這樣才對毆 要雙引號
date_default_timezone_set(“Asia/Taipei");