內容

名稱

Time::Piece - 物件導向時間物件

語法

use Time::Piece;

my $t = localtime;
print "Time is $t\n";
print "Year is ", $t->year, "\n";

說明

此模組會將標準的 localtimegmtime 函式替換為傳回物件的實作。它會以向後相容的方式執行,因此以 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

請注意,localtimegmtime 沒有列在上方。如果在 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/

注意事項 %A、%a、%B、%b 等

預設情況下,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' )

YYYY-MM-DDThh:mm:ss

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 上的執行緒中設定 $ENV{TZ}

請注意,在 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 的優秀行事曆常見問答集

錯誤

測試架構有許多需要改進的地方。歡迎提供修補程式。