Help us understand the problem. What is going on with this article?

【備忘録】DatePeriodクラスとforeachの関係性を理解する

目的

以下のコードを理解する。カレンダー機能の日付を作成しようとしている。

tdを作る
<?php

$body = '';
$period = new DatePeriod(
    new DateTime('first day of this month'),
    new DateInterval('P1D'),
    new DateTime('first day of next month')
);
foreach ($period as $day) {
    $body .= sprintf('<td>%d</td>',$day->format('d'));
}
?>

参考資料

PHP公式ドキュメント
DatePeriod クラス
DateTime クラス
DateInterval クラス

DateTimeクラスとは

日付と時刻をあらわします。

相対的な書式を用いることで、ほしい日付情報が取れる。何もかかないと、現在の日付情報が取得できる。返り値は、連想配列である。

【追記】
var_dumpについて、間違った解釈してました。

例1DateTime
$datetime = new DateTime('first day of this month');
var_dump($datetime);

$datetime1 = new DateTime();
var_dump($datetime1);
DateTimeの出力
//今月の月時刻
object(DateTime)#1 (3) { ["date"]=> string(26) "2019-10-01 01:31:24.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(10) "Asia/Tokyo" }


//現在の時刻
object(DateTime)#1 (3) { ["date"]=> string(26) "2019-10-20 01:35:11.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(10) "Asia/Tokyo" }

これぱっとみ勝手に配列と思ってたけど、object(DateTime)って書かれてるし、public、private および protected なプロパティを出力してるんだろうなー

DateIntervalとは

日付の間隔をあらわします。

格納方式は、固定値 (年、月、日、時など) あるいは相対時刻 (DateTime のコンストラクタがサポートしている書式) となります。

`
DateIntervalクラスを使用すると、返り値の要素に代入される値は、固定か、相対時刻ってことかな、、、

よくわからん

とりあえず、var_dumpしてみた

DateInterval
$interval = new DateInterval('P1D');
var_dump($interval);
DateInterval出力
object(DateInterval)#1 (15) {
  ["y"]=>
  int(0)
  ["m"]=>
  int(0)
  ["d"]=>
  int(1)
  ["h"]=>
  int(0)
  ["i"]=>
  int(0)
  ["s"]=>
  int(0)
  ["weekday"]=>
  int(0)
  ["weekday_behavior"]=>
  int(0)
  ["first_last_day_of"]=>
  int(0)
  ["invert"]=>
  int(0)
  ["days"]=>
  bool(false)
  ["special_type"]=>
  int(0)
  ["special_amount"]=>
  int(0)
  ["have_weekday_relative"]=>
  int(0)
  ["have_special_relative"]=>
  int(0)
}

["d"]=>int(1)と表示されるのは、引数にP1Dを記述して、1日間隔を指定したからだはず。

ちなみに、引数に何も入れないとエラーになる

・・・こいつの使い方よくわからねー!!!:sob:

DatePeriodとは

こいつが、DateTimeとDateIntervalを繋げる役割してるのかな、、

日付の期間をあらわします。

日付の期間を使うと、指定した期間に定期的に発生する内容を反復処理できます。

反復処理がよくわからないなー、

ドキュメント読んでみると、
コンストラクターの書き方が3パターンあるみたいだけど、冒頭のコードは以下の書き方を適用している

DatePeriod引数
public __construct ( DateTimeInterface $start , DateInterval $interval , DateTimeInterface $end [, int $options ] )

DateTimeInterfaceってのは、型宣言?ことであり、これは、DateTimeInterfaceクラスが関係しているものじゃないと、引数に代入できないですよ〜って意味。

ちなみに、DateTimeクラスのコードを見てみると、implementsDateTimeInterfaceを継承しており、すでに型宣言されている ため,DatePeriodの引数に使用できる

冒頭に記述したDatePeriodを出力してみると、
以下のようになる

DatePeriodクラス
$period = new DatePeriod(
    new DateTime('first day of this month'),
    new DateInterval('P1D'),
    new DateTime('first day of next month')
);
var_dump($period);
DatePeriod出力
 object(DatePeriod)#1 (6) { 
:--
   ["start"]=> 
   object(DateTime)#2 (3) { 
     ["date"]=> 
     string(26) "2019-10-01 09:58:53.000000" 
     ["timezone_type"]=> 
     int(3) 
     ["timezone"]=> 
     string(10) "Asia/Tokyo" 
   } 
   ["current"]=> 
   NULL 
   ["end"]=> 
   object(DateTime)#3 (3) { 
     ["date"]=> 
     string(26) "2019-11-01 09:58:53.000000" 
     ["timezone_type"]=> 
     int(3) 
     ["timezone"]=> 
     string(10) "Asia/Tokyo" 
   } 
   ["interval"]=> 
   object(DateInterval)#4 (15) { 
     ["y"]=> 
     int(0) 
     ["m"]=> 
     int(0) 
     ["d"]=> 
     int(1) 
     ["h"]=> 
     int(0) 
     ["i"]=> 
     int(0) 
     ["s"]=> 
     int(0) 
     ["weekday"]=> 
     int(0) 
     ["weekday_behavior"]=> 
     int(0) 
     ["first_last_day_of"]=> 
     int(0) 
     ["invert"]=> 
     int(0) 
     ["days"]=> 
     bool(false) 
     ["special_type"]=> 
     int(0) 
     ["special_amount"]=> 
     int(0) 
     ["have_weekday_relative"]=> 
     int(0) 
     ["have_special_relative"]=> 
     int(0) 
   } 
   ["recurrences"]=> 
   int(1) 
   ["include_start_date"]=> 
   bool(true) 
 } 

返り値は、連想配列であり、引数に代入したクラスは、以下のキーとペアになっている
配列ではありません。

[start] => new DateTime('first day of this month')
[interval] => new DateInterval('P1D')
[end] => new DateTime('first day of next month')

foreachとDateperiodについて

Dateperiodをforeachで出力すると、以下の結果になる

Dateperiodをforeahで出力
$period = new DatePeriod(
    new DateTime('first day of this month'),
    new DateInterval('P1D'),
    new DateTime('first day of next month')
);

foreach ($period as $day) {
    var_dump($day);
}

var_dump($day)の出力
 object(DateTime)#3 (3) { 
   ["date"]=> 
   string(26) "2019-10-01 19:42:43.000000" 
   ["timezone_type"]=> 
   int(3) 
   ["timezone"]=> 
   string(10) "Asia/Tokyo" 
 } 
 object(DateTime)#4 (3) { 
   ["date"]=> 
   string(26) "2019-10-02 19:42:43.000000" 
   ["timezone_type"]=> 
   int(3) 
   ["timezone"]=> 
   string(10) "Asia/Tokyo" 
 } 




 object(DateTime)#4 (3) { 
   ["date"]=> 
   string(26) "2019-10-30 20:56:25.000000" 
   ["timezone_type"]=> 
   int(3) 
   ["timezone"]=> 
   string(10) "Asia/Tokyo" 
 } 
 object(DateTime)#3 (3) { 
   ["date"]=> 
   string(26) "2019-10-31 20:56:25.000000" 
   ["timezone_type"]=> 
   int(3) 
   ["timezone"]=> 
   string(10) "Asia/Tokyo" 
 } 

DateTimeの返り値と同じような構造で、月初から月末までの日付情報を1日間隔で出力する

みたいだけど、ピンとこない:sob:

DatePeriodの返り値は、
[start],[end],[interval],[その他]なのに、
なんでforeachしただけで、DateTimeみたいな返り値がきれいに出力されるんだ?????????

Why Dateperiod ???????(厚切りアベ茶)

foreach理解してないからかなーーー
foreach嫌いだわーーー

まとめ

foreach嫌い!!!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした