程式上常會需要取用到日期或時間,Perl 的日期和時間的取得可使用內建的方法或是套件。
取得時間
使用time() 函數,會取得一個時戳( timestamp),一個長整數。
* Unix timestamp 時戳是自1970年1月1日(00:00:00 GMT)以來經過的秒數。
把時戳轉成習慣的日期時間
可使用 localtime() 函數
print "@ti"; #28 10 1 18 0 119 5 17 0
當localtime沒帶入參數的時間,會以目前時間作轉換
如果要計算某時戳的可讀日期時間,把他放在引數中即可,有鑑於PERL的彈性,下面4種寫法都可以。
my (@ti) = localtime 1501234567;
my (@ti) = localtime(1501234567);
my (@ti) = localtime "1501234567";
my (@ti) = localtime("1501234567");
localtime日期時間
localtime取回陣列是一個陣列,項目為:
秒- 0-59
分- 0-59
小時- 0-23
日- 1-31
月- 0-11,由0起算,1月顯示0,8月顯示7
年- 由1900年起算,2019年顯示 119
星期- 0-6,星期日0起算,星期六為6
一年的第幾天- 0-365,由0起算 1/1為0,年尾12/31為364或365
日光節約時間?0或1
gmtime 日期時間
和 localtime 一樣的函數,差別在於他取回的是格林威治時間。
對非格林威治時間的地區來說,你得把誤差加上去例如。台灣地區,小時數要+8。此函數使用時機為:
當你在世界各地有不同的主機,需要取得一致性的時間(例如同樣在格林威治半夜2:00傳送資料到XXX)
其它情況不要使用,以免…
例如取回的結果Taiwan
30 52 2 18 0 119 5 17 0 (localtime)
30 52 18 17 0 119 4 16 0 (gmtime)
使用清單取回各數值
PERL可以使用清單LIST的方法一次指定所有的項目
產生日期和時間格式的幾個範例
我們常用的日期格式有幾種,例如
2019-01-18
2019/01/18
01-18-2019
19-01-18
01-18-19
19-01 (不要日)
時間格式有
03:44:32
03:44 (不要秒)
等等。下面介紹幾種方法:
使用字串相黏
不想搞得太複雜的話,使用字串相黏的方式自行組合,只是要記得$year 是從1900 年啟算;而月份的話是從0起算。
$d=join("-",($year+1900,$mon+1,$day)); #2019-1-18 $d=join("-",($year+1900,$mon+1,$day)); #2019/1/18 $t=join(":",($hour,$min,$sec)); #10:4:8
這種方法取得的日期時間都如果單個數字的話都沒辦法自動補0。
採用 sprintf
$d= sprintf("%4d-%02d-%02d",$year+1900,$mon+1,$day); #2019-01-18 $t= printf("%02d:%02d:%02d",$hour,$min,$sec); #10:04:08
看來使用 sprintf就能解決所有的問題。
使用strftime
如果想給自己找麻煩的話,可以採用 strftime 函數,可以產生更多樣的格式。
但他必需要安裝 POSIX::strftime::GNU 模組,有安裝的問題可參考 [PERL] 使用CPAN安裝模組 。
由於 strftime 完全支援 localtime,使用方式,其中第一項為格式,第二項請代入 localtime的時間陣列:
$str = strftime($format, @time)
使用範例:
use POSIX::strftime::GNU; use POSIX 'strftime'; print strftime('%a, %d %b %Y %T %z', localtime); # Fri, 18 Jan 2019 02:01:43 +0800
第3行
%a 星期縮寫 Sun .. Sat
%d 日期 1-31
%b 月份縮寫
%Y 四碼年2019
%T 時間 hh:mm:ss
%z UTC時間
此函數的優點是可以以當地的語言顯示時間,例如上例要顯示中文,只要在shell指定語系
# export LC_TIME=zh_TW.UTF-8
就可以顯示中文的日期:
五, 18 1月 2019 02:18:52 +0800
有關更多的參數,可參考[2],此外,strftime的格式參數和作業系統的date格式幾乎相同 Linux shell 的date表示法 。
* 如果你不能顯示正確的中文日期時間的話,請參考這一篇 關於語系 locale 的設定
使用Date::Format 套件
使用Date::Format 套件的方法[3]
use Date::Format; print time2str("%D", time); #01/18/19 print time2str("%m/%d/%Y", time); #01/18/2019 @lt= localtime; print strftime("%a %b %e %T %Y", @lt); #Fri Jan 18 03:20:32 2019 print ctime(time); #Fri Jan 18 03:20:32 2019 print asctime(@lt); $Fri Jan 18 03:20:32 2019
說明:
time2str和strftime(和上面的strftime的套件不同函數名一樣)的差異在於一個代入要時戳,另一個是要代入陣列。
ctime和asctime也是,差異在於一個代入要時戳,另一個是要代入陣列。
第5-7行 結果一樣,因為ctime,asctime設定輸出的格式就是"%a %b %e %T %Y"
把日期時間字串轉成 timestamp
前面提到的都是把 timestamp轉成日期時間字串,相反的日期時間要轉回timestamp怎麼做?
使用Date::Manip 套件[4]
use Date::Manip; print UnixDate('2019/09/07 04:13:51', "%s"); #1567844031 print UnixDate("Fri Jan 18 03:20:32 2019", "%s"); #1547799632 print UnixDate("1st Thursday in June 1992", "%s"); #707630400
使用函數 UnixDate就能將日期字串轉成秒。
使用 ParseDate來解析字串
use Date::Manip; print $date = ParseDate("today"); #2019011900:00:00 print $date = ParseDate("now"); #2019011902:34:06 print $date = ParseDate("05/10/93"); #1993051000:00:00 print $date = ParseDate("12:30 Dec 12th 1880"); #1880121212:30:00 print $date = ParseDate("8:00pm December tenth"); #2019121020:00:00
* 字串有中文字無法解析
* 如果你的字串無法解析的話,回傳是空的字串
特別注意
設定的方式是到OS下面打入這行指令
$ export TZ=Asia/Taipei
使用Time::Local;
使用Time::Local套件提供的timelocal指令,就可以避免時區的問題,但麻煩的是字串你得自己用*regex來解。
畢竟時間字串一般都很規律,可以自己解析[5]
use Time::Local my $date = '23.01.2019 11:35:00'; my ($mday,$mon,$year,$hour,$min,$sec) = split(/[\s.:]+/, $date); my $time = timelocal($sec,$min,$hour,$mday,$mon-1,$year); #1562988900
月份是從0開始起算。
*regex 正規表達式Regular Express的非正式縮寫
結論
1. 取得時戳用 time
2. 分析時戳用 localtime(時戳)
3. 產生指定日期時間格式使用sprinft, strftime 等多種方式
4. 分析複雜日期字串用 Date::Format 套件
5. 中文字串目前無法解析
6. 日期時間的函數永遠要注意時區,考慮時區很燒腦
參考資料
[1] http://tw.gitbook.net/perl/perl_localtime.html
[2] https://metacpan.org/pod/POSIX::strftime::GNU
[3] Date::Format https://metacpan.org/pod/Date::Format
[4] Date::Manip EXAMPLE https://metacpan.org/pod/distribution/Date-Manip/lib/Date/Manip/Examples.pod
[5] https://stackoverflow.com/questions/7726514/how-to-convert-text-date-to-timestamp
上一篇 21-使用資料庫
回到目錄 01-撰寫第一隻PERL程式
下一篇 23-多執行緒
重編原文 2009-10-21 15:02:45