5

指定された 2 つの日付の間のすべての日曜日を計算したいと思います。次のコードを試しました。日数が少ない場合は問題なく動作しますが、日数を入力するとうまくいきます。処理を継続し、最大実行時間を超えて時間を変更しましたが、実行時間が 200 秒であっても処理を継続します。

コードは

<?php
$one="2013-01-01";
$two="2013-02-30";

$no=0;
for($i=$one;$i<=$two;$i++)
{

    $day=date("N",strtotime($i));
    if($day==7)
    {
    $no++;
    }
}
echo $no;

?>

助けてください。

4

3 に答える 3

30

ジョン・コンデの答えは正しいですが、より効率的で数学的な解決策は次のとおりです。

$start = new DateTime('2013-01-06');
$end = new DateTime('2013-01-20');
$days = $start->diff($end, true)->days;

$sundays = intval($days / 7) + ($start->format('N') + $days % 7 >= 7);

echo $sundays;

分解してみましょう。

$start = new DateTime('2013-01-06');
$end = new DateTime('2013-01-20');

最初に、まさにこの種の問題のための強力な組み込み PHP オブジェクトであるDateTimeオブジェクトをいくつか作成します。

$days = $start->diff($end, true)->days;

次に、DateTime::diff$startを使用してtoとの差を見つけ$end(2 番目のパラメーターとしてここを渡すtrueと、この値が常に正になることが保証されます)、それらの間の日数を取得します。

$sundays = intval($days / 7) + ($start->format('N') + $days % 7 >= 7);

ここで大きな問題が発生しますが、それほど複雑ではありません。まず、毎週日曜日が 1 つあることがわかっているため、最初は少なくとも$days / 7日曜日があり、 で最も近いものに切り捨てられintますintval

その上、1 週間未満の期間に日曜日が存在する可能性があります。たとえば、金曜日から翌週の月曜日には 4 日が含まれます。そのうちの1つは日曜日です。したがって、いつ開始して終了するかによって、別の可能性があります。これは簡単に説明できます。

  • $start->format('N')( DateTime::formatを参照) は、開始日のISO-8601曜日を示します。これは 1 から 7 までの数字です (1 は月曜日、7 は日曜日)。
  • $days % 7週に均等に分割されない残りの日数を示します。

開始日と残りの日数の合計が 7 日以上になると、日曜日に達します。それを知っているので、その式を追加するだけで、値に追加しているので、それ1が真か0偽かがわかりますint

そして、あなたはそれを持っています!この方法の利点は、指定された時刻の間を毎日反復して日曜日かどうかを確認する必要がないことです。これにより、計算が大幅に節約され、非常に賢く見えるようになります。それが役立つことを願っています!

于 2013-04-08T19:16:50.693 に答える
10
<?php
$no = 0;
$start = new DateTime('2013-01-01');
$end   = new DateTime('2013-04-30');
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt)
{
    if ($dt->format('N') == 7)
    {
        $no++;
    }
}
echo $no;

実際に見る

于 2013-04-08T18:26:16.950 に答える
1

特定の日付範囲で日曜日が必要な場合の解決策を次に示します。

function dateRange($begin, $end, $interval = null)
{
  $begin = new DateTime($begin);
  $end = new DateTime($end);

  $end = $end->modify('+1 day');
  $interval = new DateInterval($interval ? $interval : 'P1D');

  return iterator_to_array(new DatePeriod($begin, $interval, $end));
}

/* define date range */
$dates = dateRange('2018-03-01', '2018-03-31');

/* define weekdays */
$weekends = array_filter($dates, function ($date) {
  $day = $date->format("N");
  return $day === '6' || $day === '7';
});

/* weekdays output */
foreach ($weekends as $date) {
  echo $date->format("D Y-m-d") . "</br>";
}

/* define sundays */
$sundays = array_filter($dates, function ($date) {
  return $date->format("N") === '7';
});

/* sundays output */
foreach ($sundays as $date) {
echo $date->format("D Y-m-d") . "</br>";
}

/* define mondays */
$mondays = array_filter($dates, function ($date) {
 return $date->format("N") === '1';
});

/* mondays output */
foreach ($mondays as $date) {
echo $date->format("D Y-m-d") . "</br>";
}

出力に必要な日数を変更するだけです。

Monday = 1
Tuesday = 2
Wednesday = 3
Thursday = 4
Friday = 5
Saturday = 6
Sunday = 7
于 2018-03-08T09:51:11.723 に答える