teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

サンプルコードの結果を追記

2017/09/24 07:34

投稿

miyahan
miyahan

スコア3095

answer CHANGED
@@ -39,7 +39,7 @@
39
39
  {
40
40
  $date = DateTime::createFromFormat('Y年m月d日+', $date_str);
41
41
  if ($date === false) {
42
- throw new InvalidArgumentException('日付をパースきませんでした!!');
42
+ throw new InvalidArgumentException('日付が不正!!');
43
43
  }
44
44
  return $date;
45
45
  }
@@ -47,4 +47,12 @@
47
47
  $date_str = '2017年09月24日(日)';
48
48
  print('SQLスタイル: '. parseDate($date_str)->format('Y-m-d') . PHP_EOL);
49
49
  print('自然言語スタイル: '. parseDate($date_str)->format('Y/n/j') . PHP_EOL);
50
+
51
+ // SQLスタイル: 2017-09-24
52
+ // 自然言語スタイル: 2017/9/24
53
+
54
+ $date_str = '2017年09月240000000000日(日)';
55
+ print('SQLスタイル: '. parseDate($date_str)->format('Y-m-d') . PHP_EOL);
56
+
57
+ // Fatal error: Uncaught InvalidArgumentException: 日付が不正です!! in ...
50
58
  ```

1

誤り修正・サンプルコードを追加

2017/09/24 07:33

投稿

miyahan
miyahan

スコア3095

answer CHANGED
@@ -1,6 +1,6 @@
1
1
  `format()` という関数が見つからないというエラーなので、エラーが出ている行はそこではなく、`$result = $format_date->format('Y-m-d');` だと思います。
2
2
 
3
- で、format() に失敗するということは、その前の DateTime::createFromFormat() が失敗して null が返ってきているためだと思われます。
3
+ で、format() に失敗するということは、その前の DateTime::createFromFormat() が失敗して false が返ってきているためだと思われます。
4
4
 
5
5
  ```php
6
6
  $date = '2017年09月24日(日)';
@@ -12,11 +12,11 @@
12
12
  // 2017-09-24
13
13
  ```
14
14
 
15
- こちらで上記のコードを試したところエラー無く動いたので、postFilterFormat() が何か意図しない結果を返しているのだと思います。確認してみてください。
15
+ こちらで上記のコードを試したところエラー無く動いたので、postFilterFormat() とやらが意図しない結果を返しているのだと思います。確認してみてください。
16
16
 
17
17
  ---
18
18
 
19
- ちなみに DateTime の書式に、以後の文字を無視する `+` というオプションがあります。これを使うと曜日の部分: `(日)` を自分で除去しなくてもそのままパースすることができます。お試し下さい。
19
+ ちなみに DateTime::createFromFormat の書式に、以後の文字を無視する `+` という表記があります。これを使うと曜日の部分: `(日)` を自分で除去しなくてもそのままパースすることができます。お試し下さい。
20
20
 
21
21
  ```php
22
22
  function formatDate($date_str)
@@ -28,4 +28,23 @@
28
28
  print(formatDate('2017年09月24日(日)') . PHP_EOL);
29
29
  ```
30
30
 
31
- 参考:[PHP: DateTime::createFromFormat - Manual](http://php.net/manual/ja/datetime.createfromformat.php)
31
+ 参考:[PHP: DateTime::createFromFormat - Manual](http://php.net/manual/ja/datetime.createfromformat.php)
32
+
33
+ また、できればその関数は DateTime オブジェクトに変換するところまでを行い、DateTime オブジェクトから日付・時刻の文字列に format() するのはデータを実際に使うタイミング(データベースに入れるとき、printするとき等)にしたほうが汎用性が上がると思います。
34
+
35
+ さらに今回のようにエラーに気づかずにトラブルにならないよう、日付がパースできなかったら例外を投げるようにすると安全性と信頼性が高まります。
36
+
37
+ ```php
38
+ function parseDate($date_str)
39
+ {
40
+ $date = DateTime::createFromFormat('Y年m月d日+', $date_str);
41
+ if ($date === false) {
42
+ throw new InvalidArgumentException('日付をパースできませんでした!!');
43
+ }
44
+ return $date;
45
+ }
46
+
47
+ $date_str = '2017年09月24日(日)';
48
+ print('SQLスタイル: '. parseDate($date_str)->format('Y-m-d') . PHP_EOL);
49
+ print('自然言語スタイル: '. parseDate($date_str)->format('Y/n/j') . PHP_EOL);
50
+ ```