2011-11-21 20 views
0

可能重複:
In Perl, how can find the date of the previous Monday for a given date?在Perl中,我如何找到上週四的日期?

在Perl中,如何寫一個函數來獲取上週四的日期?今天(11/21),我想得到11/17。如何確定給定的日期是否爲星期日?

+1

可能重複[獲取先前週一Perl中的一個給定的日期(http://stackoverflow.com/questions/6262151/get-previous-monday-對於給定的日期在Perl中)([我的答案](http://stackoverflow.com/questions/6262151/get-previous-monday-for-a-given-date-in-perl/6262634# 6262634)這個概念被推廣到任何一天的星期幾)。 – cjm

+0

高度相關:[上週一的時間戳](http://www.perlmonks.org/?node_id=938835) – daxim

回答

7

看起來像DateTime(這是通常推薦用來在Perl中處理日期的模塊)的工作。這個小例子應該回答兩個您的問題:

use strict; 
use warnings; 

use DateTime; 

my $d = DateTime->now; 

while ($d->day_of_week != 4) { 
    $d->subtract(days => 1); 
} 

print $d->ymd; 
+0

我們有函數可以轉換爲這種格式:'20111117'? – user595234

+0

是的。 DateTime實現了一個strftime()方法。該文檔爲您提供有關格式指令的詳細信息:https://metacpan.org/module/DateTime#strftime-Patterns – larsen

+3

print $ d-> ymd(''); –

1

我會用什麼寫的拉爾森,雖然讀localtime reference不會傷害你的。你可以做這樣的事情,以檢查其週日:

($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, 
         $dayOfWeek, $dayOfYear, $daylightSavings) = localtime(); 
if ($dayOfWeek == 0) print("Don't go to work!"); 
0

如果你想測試全部是本地時間()的一天的星期幾的數組片很好地工作:

print q(Today is Sunday) if ((localtime)[6]==0) 
0

您還可以使用Date::Calc

如何計算的最後一個和下週六爲任何給定的日期?

use Date::Calc qw(Today Day_of_Week Add_Delta_Days 
        Day_of_Week_to_Text Date_to_Text); 

    $searching_dow = 6; # 6 = Saturday 

    @today = Today(); 

    $current_dow = Day_of_Week(@today); 

    if ($searching_dow == $current_dow) 
    { 
     @prev = Add_Delta_Days(@today,-7); 
     @next = Add_Delta_Days(@today,+7); 
    } 
    else 
    { 
     if ($searching_dow > $current_dow) 
     { 
      @next = Add_Delta_Days(@today, 
        $searching_dow - $current_dow); 
      @prev = Add_Delta_Days(@next,-7); 
     } 
     else 
     { 
      @prev = Add_Delta_Days(@today, 
        $searching_dow - $current_dow); 
      @next = Add_Delta_Days(@prev,+7); 
     } 
    } 

    $dow = Day_of_Week_to_Text($searching_dow); 

    print "Today is:  ", ' ' x length($dow), 
           Date_to_Text(@today), "\n"; 
    print "Last $dow was:  ", Date_to_Text(@prev), "\n"; 
    print "Next $dow will be: ", Date_to_Text(@next), "\n"; 
+0

今天是誰的日期?本地還是UTC? – ikegami

+0

正如文檔(上面鏈接)所述,'Today()'是本地時間。 '今天('utc')'(或用任何真值調用),會給你UTC。 –

0
use Date::Calc qw(:all); 

($week, $year) = Week_of_Year(Today());# Week_of_Year(2011,11,21); 
print Date_to_Text(Add_Delta_Days(Monday_of_Week($week - 1,$year),3));#THU - MON = 3 
#output:Thu 17-Nov-2011 

#isSunday? 
Day_of_Week(2011,11,20) == 7 # 7 is Sunday enum code(from 1 : Monday) 
0

日期::簡單有一個漂亮乾淨的界面。

#!/usr/bin/perl 
use strict; 
use warnings; 
use Date::Simple qw/ today /; 

my $d = today; 

# If today is already Thurs, subtract 1 before searching for prior Thursday. 
# If today is Thurs and you want to capture that (and not Thur a week ago), 
# don't subtract the 1 from $d. 
$d--; 

$d-- while $d->day_of_week != 4;  
print $d->strftime("%Y%m%d"); 
+0

今天的日期是什麼時候返回?本地還是UTC? – ikegami

+0

@ikegami不確定。通過源代碼來看,有一些像_gmtime()這樣的函數,但是害怕我不能很好地讀取代碼來查看是否使用本地時間或UTC。打印00:00 UTC之後的日期仍然給我今天的日期((New_York時區,EST) –

+0

它使用'my($ y,$ m,$ d)=(localtime)[5,4,3]; $ y + = 1900; $ m + = 1;返回$ _ [0] - > _ ymd($ y,$ m,$ d);',所以當地日期 – ikegami

0

只需localtimePOSIX基本模塊,你可以這樣做:

my @ltime = localtime(); 
my $t 
    = POSIX::mktime((0) x 3 
    , $ltime[3] - (7 - 4 + $ltime[6]) 
    , @ltime[4,5] 
    ); 

這將永遠給你的最後一個星期日前的最後一個星期四。所以如果一天是星期六,它會給你前一週的星期四,但如果是星期天,它會給你最後一個星期四。

如果你喜歡過去的過去週四的計算,你可以這樣做:

my $t 
    = POSIX::mktime((0) x 3 
    , $ltime[3] - $ltime[6] + ($ltime[6] > 4 ? 4 : -3) 
    , @ltime[4,5] 
    ); 
+0

負值對mktime無效,所以(tm_mday:月份的日期,範圍爲1到31) – ikegami

+0

@ikegami負值在'mktime'中每次都有效'I' – Axeman

+0

負數值肯定適用於'mktime';'mktime'會很樂意通過借用/傳送更高的字段來轉換任何字段中的任何超出範圍的值,這完全是它的這種能力使得它在這種計算中如此簡單而有用 – LeoNerd

6

其他崗位使用DateTime太多,但他們有問題,這個帖子的地址。

use DateTime qw(); 
my $dt = DateTime->today(time_zone => 'local'); 
$dt->subtract(days => ($dt->day_of_week - 4) % 7); 
say $dt->ymd(''); # 20111117 

所解決的問題:

  • 使用本地日期,而不是在或接近英格蘭的日期。因爲你只處理日期,所以使用today而不是now
  • 避免不必要的循環。

注:

  • 返回當前日期是今天是星期四。你接受了同樣的答案,所以我認爲這就是你想要的。

更新:以上可以在某些日子一定時間區的失效。 (並不是所有的天在半夜!)解決方案:

use DateTime qw(); 
my $dt = DateTime->now(time_zone => 'local'); 
$dt->set_time_zone('floating'); 
$dt->truncate(to => 'days'); 
$dt->subtract(days => ($dt->day_of_week - 4) % 7); 
say $dt->ymd(''); # 20111117 
+0

2011-11-21星期一運行你的代碼,我得到了20111118,而不是20111117.我用'$ dt-> subtract(days =>($ dt-> day_of_wee K + 7 - 4)%7);' –

+0

@Chris Charley,我把操作數顛倒了。固定。你的'+ 7'沒用。 '($ x + 7)%7'與'$ x%7'相同。 – ikegami

+0

我已閱讀有關模數的消息,但我並沒有真正瞭解它們。從這個問題我想我看他們是如何工作的。如果-13%7,那麼除法的結果將爲-2並且餘數爲+1(等於-13)。 –

相關問題