2016年12月11日 星期日

PHP 日期字串格式轉換方式整理

這一周來演練 PHP 爬蟲程式, 發現不同的財經網站呈現日期的方式各不相同, 有民國紀元的, 例如 "105年12月9日"; 有西元紀元的, 例如 "2016/12/9", 而且個位數的月日有的有補 0, 有些沒有, 真是傷腦筋. 我寫程式喜歡格式統一, 這樣才能前後一致, 程式碼可以一刀未剪一再重複使用. 在日期方面採用 "2016-12-09" 十個字元格式; 日期時間則採 "2016-12-09 12:08:07" 格式, 其中日期與時間以空格隔開, 這樣要拆分處理時也方便.

我將這陣子在各財經網站看到的種種日期格式轉成 "YYYY-MM-DD" 格式的處理方法整理如後備查, 這樣以後要用到時就不用到每一個專案目錄下, 一個個檔案逐一開啟來尋找, 我最討厭那種 : "咦? 我記得在這個程式中有寫過這樣的功能啊? 怎麼找不到?", 這樣漫無目標地找, 還不如重新寫較快. 但再怎麼快, 都不會比用谷歌大神搜尋自己的筆記快.

1. 證交所三大法人買賣金額統計表 : 格式 "105年12月09日"

此網頁之日期含中文且使用民國紀元, 處理起來較費事, 不過個位數的月日都已補 0, 不算是最糟的, 處理方式如下 :

//擷取交易日期:格式 "105年12月09日"
$start="<span style='float:left;margin-left:171px;'>"; //頭標
$end="三大法人買賣金額統計表"; //尾標
$trade_date=return_between($file, $start, $end, EXCL);
echo $trade_date."<br>"; //"105年12月09日"
//改為 YYY-MM-DD 格式
$trade_date=str_replace("年","-",$trade_date); //年改為 "-"
$trade_date=str_replace("月","-",$trade_date); //月改為 "-"
$trade_date=preg_replace("/[^0-9-]/","",$trade_date); //除去其餘中文部分(日)
//改為西元年 YYYY-MM-DD 格式
$arr=explode("-",$trade_date);
$arr[0] += 1911; //民國年加 1911 為西元年
$trade_date=implode("-",$arr); //組合回去
echo $trade_date."<br>";

2. 鉅亨網新台幣兌美元匯率 : 格式 "20161209"

此網頁之日期為純數字, 年月日一氣呵成絕不含糊, 而且個位數的日月都已補 0, 所以處理方式就是抓出年月日後中間插 dash 即可 :

//擷取交易日期:格式 "20161209"
$start="昨收</th></tr><tr><td>"; //頭標
$end="</td>"; //尾標
$trade_date=return_between($file, $start, $end, EXCL);
echo $trade_date."<br>";
$Y=substr($trade_date,0,4);  //取出年
$M=substr($trade_date,4,2); //取出月
$D=substr($trade_date,6,2);  //取出日
$trade_date=$Y."-".$M."-".$D;  //組合成 YYYY-MM-DD 格式
echo $trade_date."<br>";

3. 期交所三大法人區分各期期貨契約 : 格式 "2016/12/9"

此網頁預設 GET 存取的話顯示最近一次交易日全部資料, 其日期標在表格右上角. 此頁日期格式月日個位數須補 0, 處理方式如下 :

//擷取交易日期:格式 "2016/12/9"
$start='<span class="right">日期'; //頭標
$end="</span>"; //尾標
$trade_date=return_between($file, $start, $end, EXCL);
echo "交易日期=".$trade_date."<br>"; //"2016/12/9"
//改為 YYYY-MM-DD
$arr=explode("/",$trade_date); //拆出年月日以調整月日格式
if ($arr[1] < 10) {$arr[1]="0".$arr[1];} //個位數前面補 0
if ($arr[2] < 10) {$arr[2]="0".$arr[2];} //個位數前面補 0
$trade_date=implode("-",$arr); //組成 YYYY-MM-DD
echo "交易日期=".$trade_date."<br>";

4. 期交所臺股期貨 (TX) 行情表 : 格式 "2016/12/09"

此網頁是期交所期貨每日交易行情查詢頁面, 預設顯示大臺行情. 其日期位置在表格左上方, 同樣是期交所網頁, 此頁日期格式硬是跟上面期交所三大法人持倉網頁的不一樣. 不過這個好處理, 因為個位數的日月都已經補 0, 只要將斜線改成 dash 即可 :

//擷取交易日期 : 格式 "2016/12/09"
$start="<h3 align='left'>日期:"; //頭標
$end="</h3>"; //尾標
$trade_date=return_between($file, $start, $end, EXCL);
echo "交易日期=".$trade_date."<br>"; //"2016/12/09"
//改為西元年 YYYY-MM-DD
$arr=explode("/",$trade_date);
$trade_date=implode("-",$arr); //組合回去
echo "交易日期=".$trade_date."<br>";

5. Yahoo 世界股市行情表 : 格式 "12/09/2016"

Yahoo 世界股市的日期格式是月/日/年, 要轉成 YYYY-MM-DD 有點麻煩, 不僅尋標要費點手腳, 日期還要拆開重組, 所幸個位數的月日已經補 0, 省了一道手續, 處理方式如下 :

//擷取交易日期:格式 "12/09/2016"
$file=preg_replace("/[\s]{2,}/", "", $file); //去除 2 個以上空格
$start="美加</font></td>"; //頭標
$end="&nbsp;"; //尾標
$trade_date=return_between($file, $start, $end, EXCL);
//去除前面不需要的元素
$trade_date=str_replace('<td height=20 align=right>', "", $trade_date);
$trade_date=str_replace('<font color="#330066">資料日期:', "", $trade_date);
$trade_date=trim($trade_date); //刪除左右可能之空格
echo "交易日期=".$trade_date."<br>"; //"12/09/2016"
//改為西元年 YYYY-MM-DD
$arr=explode("/",$trade_date); //[0]=月,[1]=日,[2]=年
$trade_date=$arr[2]."-".$arr[0]."-".$arr[1]; //組合成 YYYY-MM-DD
echo "交易日期=".$trade_date."<br>";

2016-12-12 補充 :

奇怪, 證交所三大法人買賣金額表明明昨天還是 BIG5 編碼的網頁, 今天就改版變成 UTF-8 編碼, 導致昨天改好的程式執行失敗. 即使改為 UTF-8, 還是無法擷取成功, 仔細看網頁原始碼, 原來網頁內容也有改變, 新版網頁處理方式要改成如下 :

//擷取交易日期:格式 "105年12月09日"
$start="<span style='float:left;margin-left:223px;'>";
$end="三大法人買賣金額統計表</span>";
$trade_date=return_between($file, $start, $end, EXCL);
echo $trade_date."<br>"; //"105年12月09日"
//改為 YYY-MM-DD
$trade_date=str_replace("年","-",$trade_date); //年改為 "-"
$trade_date=str_replace("月","-",$trade_date); //月改為 "-"
$trade_date=preg_replace("/[^0-9-]/","",$trade_date); //除去其餘中文部分(日)
//改為西元年 YYYY-MM-DD
$arr=explode("-",$trade_date);
$arr[0] += 1911; //民國年加 1911 為西元年
$trade_date=implode("-",$arr); //組合回去
echo $trade_date."<br>";


沒有留言 :