Time::Piece - 物件導向時間物件
use Time::Piece;
my $t = localtime;
print "Time is $t\n";
print "Year is ", $t->year, "\n";
此模組會將標準的 localtime
和 gmtime
函式替換為傳回物件的實作。它會以向後相容的方式執行,因此以 perlfunc 中所記錄的方式使用 localtime/gmtime 仍然會傳回您預期的結果。
此模組實際上實作了 Larry Wall 在 perl5-porters 郵件串列中所描述的大部分介面:https://www.nntp.perl.org/group/perl.perl5.porters/2000/01/msg5283.html
匯入此模組後,當您在純量內容中使用 localtime 或 gmtime 時,您不會取得代表日期和時間的普通純量字串,而是會取得 Time::Piece 物件,其字串化會產生與 localtime 和 gmtime 函式相同的效果。另外也提供了 new() 建構函式,其與 localtime() 相同,但傳入 Time::Piece 物件時,它會成為複製建構函式。物件上有下列方法可用
$t->sec # also available as $t->second
$t->min # also available as $t->minute
$t->hour # 24 hour
$t->mday # also available as $t->day_of_month
$t->mon # 1 = January
$t->_mon # 0 = January
$t->monname # Feb
$t->month # same as $t->monname
$t->fullmonth # February
$t->year # based at 0 (year 0 AD is, of course 1 BC)
$t->_year # year minus 1900
$t->yy # 2 digit year
$t->wday # 1 = Sunday
$t->_wday # 0 = Sunday
$t->day_of_week # 0 = Sunday
$t->wdayname # Tue
$t->day # same as wdayname
$t->fullday # Tuesday
$t->yday # also available as $t->day_of_year, 0 = Jan 01
$t->isdst # also available as $t->daylight_savings
$t->hms # 12:34:56
$t->hms(".") # 12.34.56
$t->time # same as $t->hms
$t->ymd # 2000-02-29
$t->date # same as $t->ymd
$t->mdy # 02-29-2000
$t->mdy("/") # 02/29/2000
$t->dmy # 29-02-2000
$t->dmy(".") # 29.02.2000
$t->datetime # 2000-02-29T12:34:56 (ISO 8601)
$t->cdate # Tue Feb 29 12:34:56 2000
"$t" # same as $t->cdate
$t->epoch # seconds since the epoch
$t->tzoffset # timezone offset in a Time::Seconds object
$t->julian_day # number of days since Julian period began
$t->mjd # modified Julian date (JD-2400000.5 days)
$t->week # week number (ISO 8601)
$t->is_leap_year # true if it's a leap year
$t->month_last_day # 28-31
$t->time_separator($s) # set the default separator (default ":")
$t->date_separator($s) # set the default separator (default "-")
$t->day_list(@days) # set the default weekdays
$t->mon_list(@days) # set the default months
$t->strftime(FORMAT) # same as POSIX::strftime (without the overhead
# of the full POSIX extension)
$t->strftime() # "Tue, 29 Feb 2000 12:34:56 GMT"
Time::Piece->strptime(STRING, FORMAT)
# see strptime man page. Creates a new
# Time::Piece object
請注意,localtime
和 gmtime
沒有列在上方。如果在 Time::Piece 物件上呼叫它們作為方法,它們會作為建構函式作用,傳回目前時間的新 Time::Piece 物件。換句話說:它們作為方法時沒有用。
wdayname(星期)和 monname(月份)都允許傳遞清單,用於將日子的名稱編入索引。這在需要實作某種形式的在地化,但實際上並未安裝或使用在地化時,會很有用。請注意,這是一種全域覆寫,且會影響所有 Time::Piece 執行個體。
my @days = qw( Dimanche Lundi Merdi Mercredi Jeudi Vendredi Samedi );
my $french_day = localtime->day(@days);
這些設定也可以全域覆寫
Time::Piece::day_list(@days);
或針對月份
Time::Piece::mon_list(@months);
以及針對月份進行在地化
print localtime->month(@months);
或使用目前系統在地化呼叫來填入:Time::Piece->use_locale();
可以對物件使用簡單的加法和減法
use Time::Seconds;
my $seconds = $t1 - $t2;
$t1 += ONE_DAY; # add 1 day (constant from Time::Seconds)
下列為有效值($t1 和 $t2 為 Time::Piece 物件)
$t1 - $t2; # returns Time::Seconds object
$t1 - 42; # returns Time::Piece object
$t1 + 533; # returns Time::Piece object
不過,將 Time::Piece 物件新增到另一個 Time::Piece 物件會導致執行時期錯誤。
請注意,上述第一個會傳回 Time::Seconds 物件,因此在檢查物件時會列印秒數(因為有過載),也可以使用 Time::Seconds API 取得該增量的分鐘、小時、日、週和年數。
除了新增秒數之外,還有兩個 API 可用於新增月份和年份
$t = $t->add_months(6);
$t = $t->add_years(5);
月份和年份可以是負數,以進行減法。請注意,在月份的開頭或結尾新增和減去月份時,會出現一些「奇怪」的行為。一般來說,當結果月份比開始月份短時,就會新增重疊日數。例如,從 2008-03-31 減去一個月,結果不會是 2008-02-31,因為這是不可能的日期。相反地,你會得到 2008-03-02。這似乎與其他日期處理工具一致。
呼叫 truncate
方法會傳回物件的拷貝,但時間會截斷為提供單位的開頭。
$t = $t->truncate(to => 'day');
此範例會將時間設定為與 $t
之前相同的日期午夜。「to」參數允許的值為:「year」、「quarter」、「month」、「day」、「hour」、「minute」和「second」。
也可以使用「<」、「>」、「<=」、「>=」、「<=>」、「==」和「!=」等完整套件來進行日期比較。
Time::Piece 有內建的 strptime() 函式(來自 FreeBSD),可讓你使用彈性極高的日期剖析常式。例如
my $t = Time::Piece->strptime("Sunday 3rd Nov, 1943",
"%A %drd %b, %Y");
print $t->strftime("%a, %d %b %Y");
輸出
Wed, 03 Nov 1943
(你看,它甚至聰明到可以修正我明顯的日期錯誤)
如需更多資訊,請參閱「man strptime」,它應該存在於所有 unix 系統中。
或者,請參閱此處:http://www.unix.com/man-page/FreeBSD/3/strftime/
預設情況下,Time::Piece::strptime 只能剖析美國英語的日期名稱。同時,Time::Piece->strftime() 會傳回使用目前設定的系統在地化的日期名稱。這表示 strftime 傳回的日期可能無法由 strptime 剖析。這是預設行為,可以透過呼叫 Time::Piece->use_locale() 來覆寫。這會建立目前在地化的星期和月份名稱清單,strptime 會使用此清單來進行剖析。請注意,這是一種全域覆寫,且會影響所有 Time::Piece 執行個體。
例如,使用德語區
localtime->day_list();
傳回
( 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' )
同時
Time::Piece->use_locale();
localtime->day_list();
傳回
( 'So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa' )
ISO 8601 標準將日期格式定義為 YYYY-MM-DD,時間格式定義為 hh:mm:ss(24 小時制),如果合併使用,應先串接日期,並在時間前面加上大寫的「T」。
某些讀者可能不知道什麼是「週數」。ISO 8601 標準定義週數從星期一開始,而一年中的第 1 週是指包含 1 月 4 日和該年第一個星期四的週數。換句話說,如果 1 月的第一個星期一是 2 日、3 日或 4 日,則 1 月的前幾天屬於前一年的最後一週。週數範圍為 1 到 53。
最後,可以在匯入清單中加入「:override」標籤,以覆寫所有 localtime 和 gmtime
use Time::Piece ':override';
請注意,在 Win32 上使用 perl 的預設建置組態時(特別是在使用 PERL_IMPLICIT_SYS 建置 perl 時),每個 perl 解譯器都會維護自己的環境副本,只有主解譯器會更新 strftime 所看到的處理程序環境。
因此,如果您在非主執行緒中變更 $ENV{TZ},那麼如果您稍後使用 %Z 格式化程式碼呼叫 strftime,這些變更將不會被 strftime 看到。您必須在主執行緒中變更 $ENV{TZ},才能在此情況下產生預期的效果(您還必須在主執行緒中呼叫 _tzset() 來註冊環境變更)。
此外,請記住,此注意事項也適用於 fork(),而 fork() 在 Win32 上是由執行緒模擬的。
此模組內部使用 perl time()
函式提供的紀元秒系統,並由 gmtime()
和 localtime()
支援。
如果您的 perl 不支援大於 2^31
秒的時間,那麼此模組可能會無法處理 2038 年以後的日期。perl 中有正在進行的動作來修正此問題。或者,使用 64 位元 perl。如果這些選項都不行,請使用 DateTime 模組,它支援未來和過去的多年。
此外,Time::Piece->strftime 的內部表示與標準 POSIX 實作不同,在於它使用紀元(而非分開的年、月、日部分)。此變更已新增至版本 1.30。如果您必須使用較傳統的 strftime(通常永遠無法正確計算夏令時間),您可以將 Time::Piece 的日期部分傳遞至 POSIX 模組提供的 strftime 函式(請參閱 POSIX 中的 strftime)。
Matt Sergeant, matt@sergeant.org Jarkko Hietaniemi, jhi@iki.fi(在為核心 perl 建立 Time::Piece 時)
著作權 2001,Larry Wall。
此模組為免費軟體,您可以在與 Perl 相同的條款下散布它。
在 http://www.tondering.dk/claus/calendar.html 的優秀行事曆常見問答集
測試架構有許多需要改進的地方。歡迎提供修補程式。