0

このPERL Switch..caseステートメントがあります:

switch ($today)
{ 
    case "14-Aug-2012"  { do A }
    case "15-Aug-2012"  { do B }
}#end switch

私の問題は、「do B」ステートメントが 2012 年 8 月 15 日から 2012 年 10 月 1 日と同じであることです。これらの日付の間のケースをどのように言えば、同じことを別の日に書き直してスクリプトを長くする必要がなくなりますか?

スクリプト全体を入れたので、質問を管理するために必要なものを誰かが使用できるようになりました。

use Date::Calc
use Switch

#connect to database...

my @date_today=Today();
my $today=substr(Date_to_Text(@date_today),4,11);

Switch($today)
{
  case "14-Aug-2012" {Do A}
  case "15-Aug-2012" {Do B}
  case ...
  case ...
  case ...
}

最後の 3 つの case ステートメントは、次のようにする必要があります。

  between 16-Aug-2012 and 28-Sep-2012 {do C}
  between 29-Sep-2012 and 26-Oct-2012 {do D}
  between 27-Oct-2012 and 09-Nov-2012 {do E}
4

3 に答える 3

2

ソフトウェア エンジニアリングのアプローチを使用します。

日の範囲全体で同じことを行う必要がある場合は、その範囲の ID を個別の値として使用して選択します。次に、日付が該当する範囲 ID を示すサブルーチンを用意します。

sub range_for_date {
    my $date = shift;
    # Compute the range value in some discreet subset
    # How to compute it is somewhat irrelevant
    #      and can be asked separately if you have no idea
    # discreet subset can be an index 1..N, ecpoch timestamps,
    # or a somehow-encoded range end date (e.g. "20121001" is easy)
    # For the switch example below we will assume end dates

    return $range_id; # in "20121001" format 
}

switch (range_for_date($today)) {
    case "20121001" { do B; }
    case "20120110" { do A; }
} 
于 2012-08-15T09:20:25.760 に答える
0

もう少し簡単な別の方法を次に示します。日付を YYYYMMDD 形式に変換するだけで、数値で並べ替えたり比較したりできます。

sub sortable_date
{
    my %months;
    @months{
        'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'
    } = ('01'..'12');

    if (shift() =~ /^(\d{1,2})-(\w{3})-(\d{4})/ and exists $months{$2})
    {
        return "$3$months{$2}$1";   
    }
    else { die "invalid date format!"; }
}

switch (sortable_date($today))
{ 
    case sortable_date("14-Aug-2012")                  { do A }
    case ($_[0] >= sortable_date("15-Aug-2012") and
          $_[0] <= sortable_date("01-Oct-2012"))       { do B }
}

ただし、一般的に日付で多くのことを行う場合は、mpe のアプローチをお勧めします。

于 2012-08-15T11:43:30.297 に答える
0

日付文字列の代わりに UNIX タイムスタンプを使用します。タイムスタンプは整数であり、日付範囲に簡単に分類できます (および を使用して再フォーマットできますlocaltime())。

たとえば、Time::Localとそのtimelocal()関数を使用して、文字列をタイムスタンプに変換します。

use Time::Local;
my %months = ( # necessary because timelocal() expects month numbers, not strings
  'Jan' => 0,
  'Feb' => 1,
  'Mar' => 2,
  'Apr' => 3,
  'May' => 4,
  'Jun' => 5,
  'Jul' => 6,
  'Aug' => 7,
  'Sep' => 8,
  'Oct' => 9,
  'Nov' => 10,
  'Dec' => 11
);
my $today = '15-Aug-2012';
my @t = $today =~ /(\d{4})-(\w{3})-(\d{4})/;
$t[1] = $months{$t[1]};  # turn string into integer
my $timestamp = timelocal(0, 0, 0, @t[0, 1, 2]); # sec, min, hr, day, month, year
于 2012-08-15T09:14:05.160 に答える